]> WPIA git - gigi.git/commitdiff
add: Allow multiple names, name-schemes, multi-name-assurance, etc.
authorFelix Dörre <felix@dogcraft.de>
Thu, 14 Jul 2016 10:44:42 +0000 (12:44 +0200)
committerFelix Dörre <felix@dogcraft.de>
Fri, 22 Jul 2016 13:01:52 +0000 (15:01 +0200)
This allows for multiple names based on name schemes. Changes assurances
to verify names instead of user accounts.

Change-Id: I80d694c35e017e030a0ff381b6c611ab039091b6

52 files changed:
src/org/cacert/gigi/api/FindAgent.java
src/org/cacert/gigi/database/DatabaseConnection.java
src/org/cacert/gigi/database/tableStructure.sql
src/org/cacert/gigi/database/upgrade/from_19.sql [new file with mode: 0644]
src/org/cacert/gigi/dbObjects/Assurance.java
src/org/cacert/gigi/dbObjects/Name.java
src/org/cacert/gigi/dbObjects/NamePart.java [new file with mode: 0644]
src/org/cacert/gigi/dbObjects/SupportedUser.java
src/org/cacert/gigi/dbObjects/User.java
src/org/cacert/gigi/output/ArrayIterable.java [new file with mode: 0644]
src/org/cacert/gigi/output/AssurancesDisplay.java
src/org/cacert/gigi/output/AssurancesDisplay.templ
src/org/cacert/gigi/output/NameInput.java [new file with mode: 0644]
src/org/cacert/gigi/output/NameInput.templ [new file with mode: 0644]
src/org/cacert/gigi/pages/account/MyDetails.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/account/NamesForm.templ [new file with mode: 0644]
src/org/cacert/gigi/pages/account/certs/CertificateRequest.java
src/org/cacert/gigi/pages/admin/TTPAdminForm.java
src/org/cacert/gigi/pages/admin/TTPAdminPage.java
src/org/cacert/gigi/pages/admin/support/SupportUserDetailsForm.java
src/org/cacert/gigi/pages/admin/support/SupportUserDetailsForm.templ
src/org/cacert/gigi/pages/main/Signup.java
src/org/cacert/gigi/pages/main/Signup.templ
src/org/cacert/gigi/pages/orga/AffiliationForm.java
src/org/cacert/gigi/pages/wot/AssuranceForm.java
src/org/cacert/gigi/pages/wot/AssuranceForm.templ
src/org/cacert/gigi/pages/wot/AssurePage.java
src/org/cacert/gigi/pages/wot/MyPoints.templ
src/org/cacert/gigi/util/AuthorizationContext.java
src/org/cacert/gigi/util/Notary.java
src/org/cacert/gigi/util/PasswordStrengthChecker.java
tests/org/cacert/gigi/TestName.java
tests/org/cacert/gigi/TestObjectCache.java
tests/org/cacert/gigi/TestUser.java
tests/org/cacert/gigi/api/IssueCert.java
tests/org/cacert/gigi/api/TestFindAgent.java
tests/org/cacert/gigi/dbObjects/TestAssurance.java
tests/org/cacert/gigi/dbObjects/TestAssureName.java [new file with mode: 0644]
tests/org/cacert/gigi/pages/account/TestMyDetailsEdit.java
tests/org/cacert/gigi/pages/account/TestPasswordResetExternal.java
tests/org/cacert/gigi/pages/admin/TestSEAdminNotificationMail.java
tests/org/cacert/gigi/pages/admin/TestSEAdminPageDetails.java
tests/org/cacert/gigi/pages/wot/TestAssurance.java
tests/org/cacert/gigi/testUtils/BusinessTest.java
tests/org/cacert/gigi/testUtils/ClientBusinessTest.java
tests/org/cacert/gigi/testUtils/ConfiguredTest.java
tests/org/cacert/gigi/util/TestNotary.java
tests/org/cacert/gigi/util/TestPasswordStrengthChecker.java
util-testing/org/cacert/gigi/pages/Manager.java

index 29e536e1e1e92fd90f8113ea24e5a450a500d800..bca3a1276c73ca4cb40c5adc67250cf43b931327 100644 (file)
@@ -77,7 +77,7 @@ public class FindAgent extends APIPoint {
                     continue;
                 }
                 // date, recheck(?), name
                     continue;
                 }
                 // date, recheck(?), name
-                resp.getWriter().println(i + "," + u1.canAssure() + "," + u1.getName().toString());
+                resp.getWriter().println(i + "," + u1.canAssure() + "," + u1.getPreferredName().toAbbreviatedString());
             }
         } else if (pi.equals(PATH_MAIL)) {
             String id = req.getParameter("from");
             }
         } else if (pi.equals(PATH_MAIL)) {
             String id = req.getParameter("from");
index 39071a3d365ed643a1bc289165afb5d4a5af3e72..e7c9848812f7637ced866d04942703cd7386fddb 100644 (file)
@@ -122,7 +122,7 @@ public class DatabaseConnection {
 
     }
 
 
     }
 
-    public static final int CURRENT_SCHEMA_VERSION = 19;
+    public static final int CURRENT_SCHEMA_VERSION = 20;
 
     public static final int CONNECTION_TIMEOUT = 24 * 60 * 60;
 
 
     public static final int CONNECTION_TIMEOUT = 24 * 60 * 60;
 
index 467160cd1bfbfff0e7c5d4c0da419c9c2e1c238a..883adf769870fbf1d30085454c5b3ea25e0d3d02 100644 (file)
@@ -12,10 +12,7 @@ CREATE TABLE "users" (
   "id" int NOT NULL,
   "email" varchar(255) NOT NULL DEFAULT '',
   "password" varchar(255) NOT NULL DEFAULT '',
   "id" int NOT NULL,
   "email" varchar(255) NOT NULL DEFAULT '',
   "password" varchar(255) NOT NULL DEFAULT '',
-  "fname" varchar(255) NOT NULL DEFAULT '',
-  "mname" varchar(255) NOT NULL DEFAULT '',
-  "lname" varchar(255) NOT NULL DEFAULT '',
-  "suffix" varchar(50) NOT NULL DEFAULT '',
+  "preferredName" int NULL,
   "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 '',
@@ -377,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(19);
+INSERT INTO "schemeVersion" (version)  VALUES(20);
 
 DROP TABLE IF EXISTS `passwordResetTickets`;
 CREATE TABLE `passwordResetTickets` (
 
 DROP TABLE IF EXISTS `passwordResetTickets`;
 CREATE TABLE `passwordResetTickets` (
@@ -655,3 +652,30 @@ INSERT INTO `countryIsoCode`(english, code2, code3, obp_id) VALUES ('South Afric
 INSERT INTO `countryIsoCode`(english, code2, code3, obp_id) VALUES ('Zambia',  'ZM',  'ZMB',  894);
 INSERT INTO `countryIsoCode`(english, code2, code3, obp_id) VALUES ('Zimbabwe',  'ZW',  'ZWE',  716);
 
 INSERT INTO `countryIsoCode`(english, code2, code3, obp_id) VALUES ('Zambia',  'ZM',  'ZMB',  894);
 INSERT INTO `countryIsoCode`(english, code2, code3, obp_id) VALUES ('Zimbabwe',  'ZW',  'ZWE',  716);
 
+
+
+DROP TABLE IF EXISTS "names";
+DROP TYPE IF EXISTS "nameSchemaType";
+CREATE TYPE "nameSchemaType" AS ENUM ('single', 'western');
+
+CREATE TABLE "names" (
+  "id" serial NOT NULL,
+  "uid" int NOT NULL,
+  "type" "nameSchemaType" NOT NULL,
+  "created" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  "deleted" timestamp NULL DEFAULT NULL,
+  "deprecated" timestamp NULL DEFAULT NULL,
+  PRIMARY KEY ("id")
+);
+
+
+DROP TABLE IF EXISTS "nameParts";
+DROP TYPE IF EXISTS "namePartType";
+CREATE TYPE "namePartType" AS ENUM ('first-name', 'last-name', 'single-name', 'suffix');
+
+CREATE TABLE "nameParts" (
+  "id" int NOT NULL,
+  "position" int NOT NULL,
+  "type" "namePartType" NOT NULL,
+  "value" varchar(255) NOT NULL
+);
diff --git a/src/org/cacert/gigi/database/upgrade/from_19.sql b/src/org/cacert/gigi/database/upgrade/from_19.sql
new file mode 100644 (file)
index 0000000..ad027d6
--- /dev/null
@@ -0,0 +1,41 @@
+DROP TYPE IF EXISTS "nameSchemaType";
+CREATE TYPE "nameSchemaType" AS ENUM ('single', 'western');
+
+DROP TABLE IF EXISTS "names";
+CREATE TABLE "names" (
+  "id" serial NOT NULL,
+  "uid" int NOT NULL,
+  "type" "nameSchemaType" NOT NULL,
+  "created" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  "deleted" timestamp NULL DEFAULT NULL,
+  "deprecated" timestamp NULL DEFAULT NULL,
+  PRIMARY KEY ("id")
+);
+
+
+DROP TABLE IF EXISTS "nameParts";
+DROP TYPE IF EXISTS "namePartType";
+CREATE TYPE "namePartType" AS ENUM ('first-name', 'last-name', 'single-name', 'suffix');
+
+CREATE TABLE "nameParts" (
+  "id" int NOT NULL,
+  "position" int NOT NULL,
+  "type" "namePartType" NOT NULL,
+  "value" varchar(255) NOT NULL
+);
+
+INSERT INTO "names" ("uid", "type") (SELECT "id" as "uid", 'western'::"nameSchemaType" AS "type" from users ORDER BY id);
+INSERT INTO "nameParts" SELECT names.id, 1, 'first-name'::"namePartType", "fname" FROM "users" INNER JOIN "names" ON "names"."uid" = "users"."id";
+
+INSERT INTO "nameParts" SELECT names.id, 2, 'first-name'::"namePartType", "mname" FROM "users" INNER JOIN "names" ON "names"."uid" = "users"."id" WHERE "mname" != '';
+INSERT INTO "nameParts" SELECT names.id, 3, 'last-name'::"namePartType", "lname" FROM "users" INNER JOIN "names" ON "names"."uid" = "users"."id";
+INSERT INTO "nameParts" SELECT names.id, 4, 'suffix'::"namePartType", "suffix" FROM "users" INNER JOIN "names" ON "names"."uid" = "users"."id" WHERE "suffix" != '';
+
+UPDATE "notary" SET "to"=(SELECT "id" FROM "names" WHERE "uid"="notary"."to");
+
+ALTER TABLE "users" ADD "preferredName" int;
+UPDATE "users" SET "preferredName"=(SELECT "id" FROM "names" WHERE "uid"="users"."id");
+ALTER TABLE "users" DROP "fname";
+ALTER TABLE "users" DROP "mname";
+ALTER TABLE "users" DROP "lname";
+ALTER TABLE "users" DROP "suffix";
index 65a5a59945e98deb1a0f42a57bf322540eb6825d..dbcc20b6c2f290c75b842e2e35c4784c37b6eb98 100644 (file)
@@ -23,7 +23,7 @@ public class Assurance {
 
     private User from;
 
 
     private User from;
 
-    private User to;
+    private Name to;
 
     private String location;
 
 
     private String location;
 
@@ -33,7 +33,7 @@ public class Assurance {
 
     private String date;
 
 
     private String date;
 
-    public Assurance(int id, User from, User to, String location, String method, int points, String date) {
+    public Assurance(int id, User from, Name to, String location, String method, int points, String date) {
         this.id = id;
         this.from = from;
         this.to = to;
         this.id = id;
         this.from = from;
         this.to = to;
@@ -60,7 +60,7 @@ public class Assurance {
         return points;
     }
 
         return points;
     }
 
-    public User getTo() {
+    public Name getTo() {
         return to;
     }
 
         return to;
     }
 
index d0cf00f7d225d89be29f190aa048dacdba0d8c5d..f9099cec596e7e880cbfe5b73609e60844cd707a 100644 (file)
@@ -3,121 +3,447 @@ package org.cacert.gigi.dbObjects;
 import java.io.PrintWriter;
 import java.util.Map;
 
 import java.io.PrintWriter;
 import java.util.Map;
 
-import org.cacert.gigi.dbObjects.wrappers.DataContainer;
+import org.cacert.gigi.GigiApiException;
+import org.cacert.gigi.database.GigiPreparedStatement;
+import org.cacert.gigi.database.GigiResultSet;
+import org.cacert.gigi.dbObjects.NamePart.NamePartType;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.template.Outputable;
 import org.cacert.gigi.util.HTMLEncoder;
 
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.template.Outputable;
 import org.cacert.gigi.util.HTMLEncoder;
 
-@DataContainer
-public class Name implements Outputable {
+public class Name implements Outputable, IdCachable {
 
 
-    private final String fname;
+    private abstract static class SchemedName {
 
 
-    private final String mname;
+        /**
+         * @see Name#matches(String)
+         */
+        public abstract boolean matches(String text);
 
 
-    private final String lname;
+        public abstract String toPreferredString();
 
 
-    private final String suffix;
+        /**
+         * @see Name#toAbbreviatedString()
+         */
+        public abstract String toAbbreviatedString();
 
 
-    public Name(String fname, String lname, String mname, String suffix) {
-        this.fname = fname;
-        this.lname = lname;
-        this.mname = mname;
-        this.suffix = suffix;
-    }
+        public abstract String getSchemeName();
 
 
-    @Override
-    public void output(PrintWriter out, Language l, Map<String, Object> vars) {
-        out.println("<span class=\"accountdetail\">");
-        out.print("<span class=\"fname\">");
-        out.print(HTMLEncoder.encodeHTML(fname));
-        out.print("</span> ");
-        out.print("<span class=\"lname\">");
-        out.print(HTMLEncoder.encodeHTML(lname));
-        out.print("</span>");
-        out.println("</span>");
-    }
+        /**
+         * @see Name#output(PrintWriter, Language, Map)
+         */
+        public abstract void output(PrintWriter out);
 
 
-    @Override
-    public String toString() {
-        return fname + " " + lname;
     }
 
     }
 
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((fname == null) ? 0 : fname.hashCode());
-        result = prime * result + ((lname == null) ? 0 : lname.hashCode());
-        result = prime * result + ((mname == null) ? 0 : mname.hashCode());
-        result = prime * result + ((suffix == null) ? 0 : suffix.hashCode());
-        return result;
+    private static class SingleName extends SchemedName {
+
+        private NamePart singlePart;
+
+        public SingleName(NamePart singlePart) {
+            this.singlePart = singlePart;
+        }
+
+        @Override
+        public boolean matches(String text) {
+            return text.equals(singlePart.getValue());
+        }
+
+        @Override
+        public String toPreferredString() {
+            return singlePart.getValue();
+        }
+
+        @Override
+        public String toAbbreviatedString() {
+            return singlePart.getValue();
+        }
+
+        @Override
+        public String getSchemeName() {
+            return "single";
+        }
+
+        @Override
+        public void output(PrintWriter out) {
+            out.println("<span class='sname'>");
+            out.print(HTMLEncoder.encodeHTML(singlePart.getValue()));
+            out.println("</span>");
+        }
     }
 
     }
 
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
+    /**
+     * Naming scheme where any first name and the first last name is required.
+     * Requires first names in arbitrary order. Last names and suffixes in
+     * correct order.
+     */
+    private static class WesternName extends SchemedName {
+
+        private NamePart[] firstNames;
+
+        private NamePart[] lastNames;
+
+        private NamePart[] suffixes;
+
+        public WesternName(NamePart[] firstName, NamePart lastName[], NamePart[] suffixes) {
+            if (lastName.length < 1 || firstName.length < 1) {
+                throw new Error("Requires at least one first and one last name");
+            }
+            this.lastNames = lastName;
+            this.firstNames = firstName;
+            this.suffixes = suffixes;
         }
         }
-        if (obj == null) {
+
+        @Override
+        public boolean matches(String text) {
+            String[] tokens = text.split(" ");
+
+            NamePart mandatoryLN = lastNames[0];
+            for (int i = 0; i < tokens.length; i++) {
+                if (tokens[i].equals(mandatoryLN.getValue())) {
+                    if (tryMatchFirst(tokens, i) && tryMatchLastSuff(tokens, i)) {
+                        return true;
+                    }
+
+                }
+            }
             return false;
         }
             return false;
         }
-        if (getClass() != obj.getClass()) {
+
+        private boolean tryMatchLastSuff(String[] tokens, int lastName) {
+            int userInputPos = lastName + 1;
+            boolean currentlyMatchingLastNames = true;
+            int referencePos = 1;
+            while ((currentlyMatchingLastNames || referencePos < suffixes.length) && (userInputPos < tokens.length)) {
+                // we break when we match suffixes and there is no
+                // reference-suffix left
+                if (currentlyMatchingLastNames) {
+                    if (referencePos >= lastNames.length) {
+                        referencePos = 0;
+                        currentlyMatchingLastNames = false;
+                    } else if (tokens[userInputPos].equals(lastNames[referencePos].getValue())) {
+                        userInputPos++;
+                        referencePos++;
+                    } else {
+                        referencePos++;
+                    }
+                } else {
+                    if (tokens[userInputPos].equals(suffixes[referencePos].getValue())) {
+                        userInputPos++;
+                        referencePos++;
+                    } else {
+                        referencePos++;
+                    }
+                }
+            }
+            if (userInputPos >= tokens.length) {
+                // all name parts are covered we're done here
+                return true;
+            }
             return false;
         }
             return false;
         }
-        Name other = (Name) obj;
-        if (fname == null) {
-            if (other.fname != null) {
+
+        private boolean tryMatchFirst(String[] tokens, int lastName) {
+            if (lastName == 0) {
                 return false;
             }
                 return false;
             }
-        } else if ( !fname.equals(other.fname)) {
-            return false;
+            boolean[] fnUsed = new boolean[firstNames.length];
+            for (int i = 0; i < lastName; i++) {
+                boolean found = false;
+                for (int j = 0; j < fnUsed.length; j++) {
+                    if ( !fnUsed[j] && firstNames[j].getValue().equals(tokens[i])) {
+                        fnUsed[j] = true;
+                        found = true;
+                        break;
+                    }
+                }
+                if ( !found) {
+                    return false;
+                }
+            }
+            return true;
         }
         }
-        if (lname == null) {
-            if (other.lname != null) {
-                return false;
+
+        @Override
+        public String toPreferredString() {
+            StringBuilder res = new StringBuilder();
+            appendArray(res, firstNames);
+            appendArray(res, lastNames);
+            appendArray(res, suffixes);
+            res.deleteCharAt(res.length() - 1);
+            return res.toString();
+        }
+
+        @Override
+        public void output(PrintWriter out) {
+            outputNameParts(out, "fname", firstNames);
+            outputNameParts(out, "lname", lastNames);
+            outputNameParts(out, "suffix", suffixes);
+        }
+
+        private void outputNameParts(PrintWriter out, String type, NamePart[] input) {
+            StringBuilder res;
+            res = new StringBuilder();
+            appendArray(res, input);
+            if (res.length() > 0) {
+                res.deleteCharAt(res.length() - 1);
+                out.print("<span class='" + type + "'>");
+                out.print(HTMLEncoder.encodeHTML(res.toString()));
+                out.println("</span>");
             }
             }
-        } else if ( !lname.equals(other.lname)) {
-            return false;
         }
         }
-        if (mname == null) {
-            if (other.mname != null) {
-                return false;
+
+        private void appendArray(StringBuilder res, NamePart[] ps) {
+            for (int i = 0; i < ps.length; i++) {
+                res.append(ps[i].getValue());
+                res.append(" ");
             }
             }
-        } else if ( !mname.equals(other.mname)) {
-            return false;
         }
         }
-        if (suffix == null) {
-            if (other.suffix != null) {
-                return false;
+
+        @Override
+        public String getSchemeName() {
+            return "western";
+        }
+
+        @Override
+        public String toAbbreviatedString() {
+            return firstNames[0].getValue() + " " + lastNames[0].getValue().charAt(0) + ".";
+        }
+    }
+
+    private int id;
+
+    private int ownerId;
+
+    /**
+     * Only resolved lazily to resolve circular referencing with {@link User} on
+     * {@link User#getPreferredName()}. Resolved based on {@link #ownerId}.
+     */
+    private User owner;
+
+    private NamePart[] parts;
+
+    private SchemedName scheme;
+
+    /**
+     * This name should not get assured anymore and therefore not be displayed
+     * to the RA-Agent. This state is irrevocable.
+     */
+    private boolean deprecated;
+
+    private Name(GigiResultSet rs) {
+        ownerId = rs.getInt(1);
+        id = rs.getInt(2);
+        deprecated = rs.getString("deprecated") != null;
+        try (GigiPreparedStatement partFetcher = new GigiPreparedStatement("SELECT `type`, `value` FROM `nameParts` WHERE `id`=? ORDER BY `position` ASC", true)) {
+            partFetcher.setInt(1, id);
+            GigiResultSet rs1 = partFetcher.executeQuery();
+            rs1.last();
+            NamePart[] dt = new NamePart[rs1.getRow()];
+            rs1.beforeFirst();
+            for (int i = 0; rs1.next(); i++) {
+                dt[i] = new NamePart(rs1);
             }
             }
-        } else if ( !suffix.equals(other.suffix)) {
-            return false;
+            parts = dt;
+            scheme = detectScheme();
         }
         }
-        return true;
+
     }
 
     }
 
+    public Name(User u, NamePart... np) throws GigiApiException {
+        synchronized (Name.class) {
+            parts = np;
+            owner = u;
+            scheme = detectScheme();
+            if (scheme == null) {
+                throw new GigiApiException("Name particles don't match up for any known name scheme.");
+            }
+            try (GigiPreparedStatement inserter = new GigiPreparedStatement("INSERT INTO `names` SET `uid`=?, `type`=?::`nameSchemaType`")) {
+                inserter.setInt(1, u.getId());
+                inserter.setString(2, scheme.getSchemeName());
+                inserter.execute();
+                id = inserter.lastInsertId();
+            }
+            try (GigiPreparedStatement inserter = new GigiPreparedStatement("INSERT INTO `nameParts` SET `id`=?, `position`=?, `type`=?::`namePartType`, `value`=?")) {
+                inserter.setInt(1, id);
+                for (int i = 0; i < np.length; i++) {
+                    inserter.setInt(2, i);
+                    inserter.setString(3, np[i].getType().getDbValue());
+                    inserter.setString(4, np[i].getValue());
+                    inserter.execute();
+                }
+            }
+            cache.put(this);
+        }
+    }
+
+    private SchemedName detectScheme() {
+        if (parts.length == 1 && parts[0].getType() == NamePartType.SINGLE_NAME) {
+            return new SingleName(parts[0]);
+        }
+        int suffixCount = 0;
+        int lastCount = 0;
+        int firstCount = 0;
+        int stage = 0;
+        for (NamePart p : parts) {
+            if (p.getType() == NamePartType.LAST_NAME) {
+                lastCount++;
+                if (stage < 1) {
+                    stage = 1;
+                } else if (stage != 1) {
+                    return null;
+                }
+            } else if (p.getType() == NamePartType.FIRST_NAME) {
+                firstCount++;
+                if (stage != 0) {
+                    return null;
+                }
+            } else if (p.getType() == NamePartType.SUFFIX) {
+                suffixCount++;
+                if (stage < 2) {
+                    stage = 2;
+                } else if (stage != 2) {
+                    return null;
+                }
+
+            } else {
+                return null;
+            }
+        }
+        if (firstCount == 0 || lastCount == 0) {
+            return null;
+        }
+        NamePart[] firstNames = new NamePart[firstCount];
+        NamePart[] lastNames = new NamePart[lastCount];
+        NamePart[] suffixes = new NamePart[suffixCount];
+        int fn = 0;
+        int ln = 0;
+        int sn = 0;
+        for (NamePart p : parts) {
+            if (p.getType() == NamePartType.FIRST_NAME) {
+                firstNames[fn++] = p;
+            } else if (p.getType() == NamePartType.SUFFIX) {
+                suffixes[sn++] = p;
+            } else if (p.getType() == NamePartType.LAST_NAME) {
+                lastNames[ln++] = p;
+            }
+        }
+
+        return new WesternName(firstNames, lastNames, suffixes);
+    }
+
+    /**
+     * Outputs an HTML variant suitable for locations where special UI features
+     * should indicate the different Name Parts.
+     */
+    @Override
+    public void output(PrintWriter out, Language l, Map<String, Object> vars) {
+        out.print("<span class=\"names\">");
+        scheme.output(out);
+        out.print("</span> ");
+    }
+
+    /**
+     * Tests, if this name fits into the given string.
+     * 
+     * @param text
+     *            the name to test against
+     * @return true, iff this name matches.
+     */
     public boolean matches(String text) {
     public boolean matches(String text) {
-        return text.equals(fname + " " + lname) || //
-                (mname != null && text.equals(fname + " " + mname + " " + lname)) || //
-                (suffix != null && text.equals(fname + " " + lname + " " + suffix)) || //
-                (mname != null && suffix != null && text.equals(fname + " " + mname + " " + lname + " " + suffix));
+        if ( !text.equals(text.trim())) {
+            return false;
+        }
+        return scheme.matches(text);
     }
 
     }
 
-    public String getFname() {
-        return fname;
+    @Override
+    public String toString() {
+        return scheme.toPreferredString();
     }
 
     }
 
-    public String getLname() {
-        return lname;
+    /**
+     * Transforms this String into a short form. This short form should not be
+     * unique. (For "western" names this would be
+     * "firstName firstCharOfLastName.".)
+     * 
+     * @return the short form of the name
+     */
+    public String toAbbreviatedString() {
+        return scheme.toAbbreviatedString();
     }
 
     }
 
-    public String getMname() {
-        return mname;
+    public int getAssurancePoints() {
+        try (GigiPreparedStatement query = new GigiPreparedStatement("SELECT SUM(`points`) FROM (SELECT DISTINCT ON (`from`) `points` FROM `notary` WHERE `to`=? AND `deleted` IS NULL AND (`expire` IS NULL OR `expire` > CURRENT_TIMESTAMP) ORDER BY `from`, `when` DESC) AS p")) {
+            query.setInt(1, getId());
+
+            GigiResultSet rs = query.executeQuery();
+            int points = 0;
+
+            if (rs.next()) {
+                points = rs.getInt(1);
+            }
+
+            return points;
+        }
     }
 
     }
 
-    public String getSuffix() {
-        return suffix;
+    @Override
+    public int getId() {
+        return id;
     }
 
     }
 
+    private static ObjectCache<Name> cache = new ObjectCache<>();
+
+    public synchronized static Name getById(int id) {
+        Name cacheRes = cache.get(id);
+        if (cacheRes != null) {
+            return cacheRes;
+        }
+
+        try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT `uid`, `id`, `deprecated` FROM `names` WHERE `deleted` IS NULL AND `id` = ?")) {
+            ps.setInt(1, id);
+            GigiResultSet rs = ps.executeQuery();
+            if ( !rs.next()) {
+                return null;
+            }
+
+            Name c = new Name(rs);
+            cache.put(c);
+            return c;
+        }
+    }
+
+    public NamePart[] getParts() {
+        return parts;
+    }
+
+    public void remove() {
+        synchronized (Name.class) {
+            cache.remove(this);
+            try (GigiPreparedStatement ps = new GigiPreparedStatement("UPDATE `names` SET `deleted` = now() WHERE `id`=?")) {
+                ps.setInt(1, id);
+                ps.executeUpdate();
+            }
+        }
+    }
+
+    public synchronized void deprecate() {
+        deprecated = true;
+        try (GigiPreparedStatement ps = new GigiPreparedStatement("UPDATE `names` SET `deprecated`=now() WHERE `id`=?")) {
+            ps.setInt(1, id);
+            ps.executeUpdate();
+        }
+    }
+
+    public boolean isDeprecated() {
+        return deprecated;
+    }
+
+    public synchronized User getOwner() {
+        if (owner == null) {
+            owner = User.getById(ownerId);
+        }
+        return owner;
+    }
 }
 }
diff --git a/src/org/cacert/gigi/dbObjects/NamePart.java b/src/org/cacert/gigi/dbObjects/NamePart.java
new file mode 100644 (file)
index 0000000..42464b7
--- /dev/null
@@ -0,0 +1,81 @@
+package org.cacert.gigi.dbObjects;
+
+import org.cacert.gigi.database.GigiResultSet;
+import org.cacert.gigi.dbObjects.wrappers.DataContainer;
+
+@DataContainer
+public class NamePart {
+
+    public enum NamePartType {
+        FIRST_NAME, LAST_NAME, SINGLE_NAME, SUFFIX;
+
+        public String getDbValue() {
+            return name().toLowerCase().replace("_", "-");
+        }
+    }
+
+    private NamePartType type;
+
+    private String value;
+
+    public NamePart(NamePartType type, String value) {
+        if (type == null || value == null || value.trim().isEmpty() || !value.trim().equals(value)) {
+            throw new IllegalArgumentException();
+        }
+        this.type = type;
+        this.value = value;
+    }
+
+    public NamePart(GigiResultSet rs1) {
+        value = rs1.getString("value");
+        type = NamePartType.valueOf(rs1.getString("type").replace("-", "_").toUpperCase());
+    }
+
+    public NamePartType getType() {
+        return type;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return value;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        result = prime * result + ((value == null) ? 0 : value.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        NamePart other = (NamePart) obj;
+        if (type != other.type) {
+            return false;
+        }
+        if (value == null) {
+            if (other.value != null) {
+                return false;
+            }
+        } else if ( !value.equals(other.value)) {
+            return false;
+        }
+        return true;
+    }
+
+}
index 7affe34caa18c35625e8a0cff56ab02d10248469..193a32b0853492069c33059b007510c2636eb279 100644 (file)
@@ -30,21 +30,12 @@ public class SupportedUser {
         this.ticket = ticket;
     }
 
         this.ticket = ticket;
     }
 
-    public boolean setName(Name newName) throws GigiApiException {
-        if (newName.equals(target.getName())) {
-            return false;
-        }
-        writeSELog("SE Name change");
-        target.setName(newName);
-        return true;
-    }
-
     public boolean setDob(DayDate dob) throws GigiApiException {
         if (dob.equals(target.getDoB())) {
             return false;
         }
         writeSELog("SE dob change");
     public boolean setDob(DayDate dob) throws GigiApiException {
         if (dob.equals(target.getDoB())) {
             return false;
         }
         writeSELog("SE dob change");
-        target.setDoB(dob);
+        target.setDoBAsSupport(dob);
         return true;
     }
 
         return true;
     }
 
@@ -88,10 +79,6 @@ public class SupportedUser {
         return target;
     }
 
         return target;
     }
 
-    public void submitSupportAction() throws GigiApiException {
-        target.rawUpdateUserData();
-    }
-
     public void grant(Group toMod) {
         target.grantGroup(supporter, toMod);
     }
     public void grant(Group toMod) {
         target.grantGroup(supporter, toMod);
     }
@@ -105,7 +92,7 @@ public class SupportedUser {
             StringWriter sw = new StringWriter();
             PrintWriter outMail = new PrintWriter(sw);
             outMail.print("Hi," + "\n\n");
             StringWriter sw = new StringWriter();
             PrintWriter outMail = new PrintWriter(sw);
             outMail.print("Hi," + "\n\n");
-            SprintfCommand.createSimple("supporter {0} triggered:", supporter.getName().toString()).output(outMail, Language.getInstance(Locale.ENGLISH), new HashMap<String, Object>());
+            SprintfCommand.createSimple("supporter {0} triggered:", supporter.getPreferredName().toString()).output(outMail, Language.getInstance(Locale.ENGLISH), new HashMap<String, Object>());
             outMail.print("\n\n");
             message.output(outMail, Language.getInstance(Locale.ENGLISH), new HashMap<String, Object>());
             outMail.print("\n\n");
             outMail.print("\n\n");
             message.output(outMail, Language.getInstance(Locale.ENGLISH), new HashMap<String, Object>());
             outMail.print("\n\n");
index d3d5da02e3a1dc7c65a01b0c9531f9e98b0fb223..91ab46cbe8b3c70aa081208ad0b75c4abe683199 100644 (file)
@@ -28,8 +28,6 @@ import org.cacert.gigi.util.PasswordStrengthChecker;
  */
 public class User extends CertificateOwner {
 
  */
 public class User extends CertificateOwner {
 
-    private Name name = new Name(null, null, null, null);
-
     private DayDate dob;
 
     private String email;
     private DayDate dob;
 
     private String email;
@@ -55,15 +53,17 @@ public class User extends CertificateOwner {
      */
     public static final int VERIFICATION_MONTHS = 39;
 
      */
     public static final int VERIFICATION_MONTHS = 39;
 
+    private Name preferredName;
+
     protected User(GigiResultSet rs) {
         super(rs.getInt("id"));
         updateName(rs);
     }
 
     private void updateName(GigiResultSet rs) {
     protected User(GigiResultSet rs) {
         super(rs.getInt("id"));
         updateName(rs);
     }
 
     private void updateName(GigiResultSet rs) {
-        name = new Name(rs.getString("fname"), rs.getString("lname"), rs.getString("mname"), rs.getString("suffix"));
         dob = new DayDate(rs.getDate("dob"));
         email = rs.getString("email");
         dob = new DayDate(rs.getDate("dob"));
         email = rs.getString("email");
+        preferredName = Name.getById(rs.getInt("preferredName"));
 
         String localeStr = rs.getString("language");
         if (localeStr == null || localeStr.equals("")) {
 
         String localeStr = rs.getString("language");
         if (localeStr == null || localeStr.equals("")) {
@@ -83,36 +83,68 @@ public class User extends CertificateOwner {
         }
     }
 
         }
     }
 
-    public User(String email, String password, Name name, DayDate dob, Locale locale) throws GigiApiException {
+    public User(String email, String password, DayDate dob, Locale locale, NamePart... preferred) throws GigiApiException {
         this.email = email;
         this.dob = dob;
         this.email = email;
         this.dob = dob;
-        this.name = name;
         this.locale = locale;
         this.locale = locale;
-        try (GigiPreparedStatement query = new GigiPreparedStatement("INSERT INTO `users` SET `email`=?, `password`=?, " + "`fname`=?, `mname`=?, `lname`=?, " + "`suffix`=?, `dob`=?, `language`=?, id=?")) {
+        this.preferredName = new Name(this, preferred);
+        try (GigiPreparedStatement query = new GigiPreparedStatement("INSERT INTO `users` SET `email`=?, `password`=?, `dob`=?, `language`=?, id=?, `preferredName`=?")) {
             query.setString(1, email);
             query.setString(2, PasswordHash.hash(password));
             query.setString(1, email);
             query.setString(2, PasswordHash.hash(password));
-            query.setString(3, name.getFname());
-            query.setString(4, name.getMname());
-            query.setString(5, name.getLname());
-            query.setString(6, name.getSuffix());
-            query.setDate(7, dob.toSQLDate());
-            query.setString(8, locale.toString());
-            query.setInt(9, getId());
+            query.setDate(3, dob.toSQLDate());
+            query.setString(4, locale.toString());
+            query.setInt(5, getId());
+            query.setInt(6, preferredName.getId());
             query.execute();
         }
         new EmailAddress(this, email, locale);
     }
 
             query.execute();
         }
         new EmailAddress(this, email, locale);
     }
 
-    public Name getName() {
-        return name;
+    public Name[] getNames() {
+        try (GigiPreparedStatement gps = new GigiPreparedStatement("SELECT `id` FROM `names` WHERE `uid`=? AND `deleted` IS NULL", true)) {
+            return fetchNamesToArray(gps);
+        }
+    }
+
+    public Name[] getNonDeprecatedNames() {
+        try (GigiPreparedStatement gps = new GigiPreparedStatement("SELECT `id` FROM `names` WHERE `uid`=? AND `deleted` IS NULL AND `deprecated` IS NULL", true)) {
+            return fetchNamesToArray(gps);
+        }
+    }
+
+    private Name[] fetchNamesToArray(GigiPreparedStatement gps) {
+        gps.setInt(1, getId());
+        GigiResultSet rs = gps.executeQuery();
+        rs.last();
+        Name[] dt = new Name[rs.getRow()];
+        rs.beforeFirst();
+        for (int i = 0; rs.next(); i++) {
+            dt[i] = Name.getById(rs.getInt(1));
+        }
+        return dt;
     }
 
     public DayDate getDoB() {
         return dob;
     }
 
     }
 
     public DayDate getDoB() {
         return dob;
     }
 
-    public void setDoB(DayDate dob) {
-        this.dob = dob;
+    public void setDoB(DayDate dob) throws GigiApiException {
+        synchronized (Notary.class) {
+            if (getReceivedAssurances().length != 0) {
+                throw new GigiApiException("No change after assurance allowed.");
+            }
+            this.dob = dob;
+            rawUpdateUserData();
+        }
+
+    }
+
+    protected void setDoBAsSupport(DayDate dob) throws GigiApiException {
+        synchronized (Notary.class) {
+            this.dob = dob;
+            rawUpdateUserData();
+        }
+
     }
 
     public String getEmail() {
     }
 
     public String getEmail() {
@@ -135,7 +167,7 @@ public class User extends CertificateOwner {
     }
 
     private void setPassword(String newPass) throws GigiApiException {
     }
 
     private void setPassword(String newPass) throws GigiApiException {
-        PasswordStrengthChecker.assertStrongPassword(newPass, getName(), getEmail());
+        PasswordStrengthChecker.assertStrongPassword(newPass, getNames(), getEmail());
         try (GigiPreparedStatement ps = new GigiPreparedStatement("UPDATE users SET `password`=? WHERE id=?")) {
             ps.setString(1, PasswordHash.hash(newPass));
             ps.setInt(2, getId());
         try (GigiPreparedStatement ps = new GigiPreparedStatement("UPDATE users SET `password`=? WHERE id=?")) {
             ps.setString(1, PasswordHash.hash(newPass));
             ps.setInt(2, getId());
@@ -143,10 +175,6 @@ public class User extends CertificateOwner {
         }
     }
 
         }
     }
 
-    public void setName(Name name) {
-        this.name = name;
-    }
-
     public boolean canAssure() {
         if (POJAM_ENABLED) {
             if ( !CalendarUtil.isOfAge(dob, POJAM_AGE)) { // PoJAM
     public boolean canAssure() {
         if (POJAM_ENABLED) {
             if ( !CalendarUtil.isOfAge(dob, POJAM_AGE)) { // PoJAM
@@ -180,7 +208,7 @@ public class User extends CertificateOwner {
     }
 
     public int getAssurancePoints() {
     }
 
     public int getAssurancePoints() {
-        try (GigiPreparedStatement query = new GigiPreparedStatement("SELECT SUM(lastpoints) FROM ( SELECT DISTINCT ON (`from`) `from`, `to`, `points` as lastpoints, `method` FROM `notary` WHERE `deleted` is NULL AND (`expire` IS NULL OR `expire` > CURRENT_TIMESTAMP) AND `to` = ? ORDER BY  `from`, `when` DESC) as p")) {
+        try (GigiPreparedStatement query = new GigiPreparedStatement("SELECT SUM(lastpoints) FROM ( SELECT DISTINCT ON (`from`) `from`, `points` as lastpoints FROM `notary` INNER JOIN `names` ON `names`.`id`=`to` WHERE `notary`.`deleted` is NULL AND (`expire` IS NULL OR `expire` > CURRENT_TIMESTAMP) AND `names`.`uid` = ? ORDER BY `from`, `when` DESC) as p")) {
             query.setInt(1, getId());
 
             GigiResultSet rs = query.executeQuery();
             query.setInt(1, getId());
 
             GigiResultSet rs = query.executeQuery();
@@ -195,7 +223,7 @@ public class User extends CertificateOwner {
     }
 
     public int getExperiencePoints() {
     }
 
     public int getExperiencePoints() {
-        try (GigiPreparedStatement query = new GigiPreparedStatement("SELECT count(*) FROM ( SELECT `to` FROM `notary` WHERE `from`=? AND `deleted` IS NULL AND `method` = ? ::`notaryType` GROUP BY `to`) as p")) {
+        try (GigiPreparedStatement query = new GigiPreparedStatement("SELECT count(*) FROM ( SELECT `names`.`uid` FROM `notary` INNER JOIN `names` ON `names`.`id` = `to` WHERE `from`=? AND `notary`.`deleted` IS NULL AND `method` = ? ::`notaryType` GROUP BY `names`.`uid`) as p")) {
             query.setInt(1, getId());
             query.setString(2, AssuranceType.FACE_TO_FACE.getDescription());
 
             query.setInt(1, getId());
             query.setString(2, AssuranceType.FACE_TO_FACE.getDescription());
 
@@ -244,7 +272,12 @@ public class User extends CertificateOwner {
     }
 
     public boolean isValidName(String name) {
     }
 
     public boolean isValidName(String name) {
-        return getName().matches(name);
+        for (Name n : getNames()) {
+            if (n.matches(name) && n.getAssurancePoints() >= 50) {
+                return true;
+            }
+        }
+        return false;
     }
 
     public void updateDefaultEmail(EmailAddress newMail) throws GigiApiException {
     }
 
     public void updateDefaultEmail(EmailAddress newMail) throws GigiApiException {
@@ -287,7 +320,7 @@ public class User extends CertificateOwner {
 
     public synchronized Assurance[] getReceivedAssurances() {
         if (receivedAssurances == null) {
 
     public synchronized Assurance[] getReceivedAssurances() {
         if (receivedAssurances == null) {
-            try (GigiPreparedStatement query = new GigiPreparedStatement("SELECT * FROM `notary` WHERE `to`=? AND `deleted` IS NULL")) {
+            try (GigiPreparedStatement query = new GigiPreparedStatement("SELECT * FROM `notary` INNER JOIN `names` ON `names`.`id` = `notary`.`to` WHERE `names`.`uid`=? AND `notary`.`deleted` IS NULL")) {
                 query.setInt(1, getId());
 
                 GigiResultSet res = query.executeQuery();
                 query.setInt(1, getId());
 
                 GigiResultSet res = query.executeQuery();
@@ -332,23 +365,10 @@ public class User extends CertificateOwner {
         receivedAssurances = null;
     }
 
         receivedAssurances = null;
     }
 
-    public void updateUserData() throws GigiApiException {
-        synchronized (Notary.class) {
-            if (getReceivedAssurances().length != 0) {
-                throw new GigiApiException("No change after assurance allowed.");
-            }
-            rawUpdateUserData();
-        }
-    }
-
-    protected void rawUpdateUserData() {
-        try (GigiPreparedStatement update = new GigiPreparedStatement("UPDATE users SET fname=?, lname=?, mname=?, suffix=?, dob=? WHERE id=?")) {
-            update.setString(1, name.getFname());
-            update.setString(2, name.getLname());
-            update.setString(3, name.getMname());
-            update.setString(4, name.getSuffix());
-            update.setDate(5, getDoB().toSQLDate());
-            update.setInt(6, getId());
+    private void rawUpdateUserData() {
+        try (GigiPreparedStatement update = new GigiPreparedStatement("UPDATE users SET dob=? WHERE id=?")) {
+            update.setDate(1, getDoB().toSQLDate());
+            update.setInt(2, getId());
             update.executeUpdate();
         }
     }
             update.executeUpdate();
         }
     }
@@ -362,6 +382,23 @@ public class User extends CertificateOwner {
 
     }
 
 
     }
 
+    public Name getPreferredName() {
+        return preferredName;
+    }
+
+    public synchronized void setPreferredName(Name preferred) throws GigiApiException {
+        if (preferred.getOwner() != this) {
+            throw new GigiApiException("Cannot set a name as preferred one that does not belong to this account.");
+        }
+        this.preferredName = preferred;
+        try (GigiPreparedStatement ps = new GigiPreparedStatement("UPDATE `users` SET `preferredName`=? WHERE `id`=?")) {
+            ps.setInt(1, preferred.getId());
+            ps.setInt(2, getId());
+            ps.executeUpdate();
+        }
+
+    }
+
     public boolean isInGroup(Group g) {
         return groups.contains(g);
     }
     public boolean isInGroup(Group g) {
         return groups.contains(g);
     }
@@ -539,11 +576,11 @@ public class User extends CertificateOwner {
     }
 
     private Assurance assuranceByRes(GigiResultSet res) {
     }
 
     private Assurance assuranceByRes(GigiResultSet res) {
-        return new Assurance(res.getInt("id"), User.getById(res.getInt("from")), User.getById(res.getInt("to")), res.getString("location"), res.getString("method"), res.getInt("points"), res.getString("date"));
+        return new Assurance(res.getInt("id"), User.getById(res.getInt("from")), Name.getById(res.getInt("to")), res.getString("location"), res.getString("method"), res.getInt("points"), res.getString("date"));
     }
 
     public boolean isInVerificationLimit() {
     }
 
     public boolean isInVerificationLimit() {
-        try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT 1 FROM `notary` WHERE `to` = ? AND `when` > (now() - (interval '1 month' * ?)) AND (`expire` IS NULL OR `expire` > now()) AND `deleted` IS NULL;")) {
+        try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT 1 FROM `notary` INNER JOIN `names` ON `names`.`id`=`to` WHERE `names`.`uid` = ? AND `when` > (now() - (interval '1 month' * ?)) AND (`expire` IS NULL OR `expire` > now()) AND `notary`.`deleted` IS NULL;")) {
             ps.setInt(1, getId());
             ps.setInt(2, VERIFICATION_MONTHS);
 
             ps.setInt(1, getId());
             ps.setInt(2, VERIFICATION_MONTHS);
 
@@ -551,4 +588,5 @@ public class User extends CertificateOwner {
             return rs.next();
         }
     }
             return rs.next();
         }
     }
+
 }
 }
diff --git a/src/org/cacert/gigi/output/ArrayIterable.java b/src/org/cacert/gigi/output/ArrayIterable.java
new file mode 100644 (file)
index 0000000..90bad43
--- /dev/null
@@ -0,0 +1,30 @@
+package org.cacert.gigi.output;
+
+import java.util.Map;
+
+import org.cacert.gigi.localisation.Language;
+import org.cacert.gigi.output.template.IterableDataset;
+
+public abstract class ArrayIterable<T> implements IterableDataset {
+
+    private T[] dt;
+
+    protected int i = 0;
+
+    public ArrayIterable(T[] dt) {
+        this.dt = dt;
+    }
+
+    @Override
+    public boolean next(Language l, Map<String, Object> vars) {
+        if (i >= dt.length) {
+            return false;
+        }
+        apply(dt[i], l, vars);
+        i++;
+        return true;
+    }
+
+    public abstract void apply(T t, Language l, Map<String, Object> vars);
+
+}
index 9cd7558c1e54d5bc6dd65d7b2159a685c8a27238..2266c6e8283966c69b358415f65fb9d7d5e1bc06 100644 (file)
@@ -29,6 +29,7 @@ public class AssurancesDisplay implements Outputable {
             vars.put("verb", l.getTranslation("To"));
         } else {
             vars.put("verb", l.getTranslation("From"));
             vars.put("verb", l.getTranslation("To"));
         } else {
             vars.put("verb", l.getTranslation("From"));
+            vars.put("myName", "yes");
         }
 
         IterableDataset assuranceGroup = new IterableDataset() {
         }
 
         IterableDataset assuranceGroup = new IterableDataset() {
@@ -44,9 +45,11 @@ public class AssurancesDisplay implements Outputable {
                     vars.put("id", assurance.getId());
                     vars.put("method", assurance.getMethod());
                     if (assurer) {
                     vars.put("id", assurance.getId());
                     vars.put("method", assurance.getMethod());
                     if (assurer) {
-                        vars.put("verbVal", assurance.getTo().getName());
+                        vars.put("verbVal", assurance.getTo().getOwner().getPreferredName());
+                        vars.put("myName", assurance.getTo());
                     } else {
                     } else {
-                        vars.put("verbVal", assurance.getFrom().getName());
+                        vars.put("verbVal", assurance.getFrom().getPreferredName());
+                        vars.put("myName", assurance.getTo());
                     }
                     vars.put("date", assurance.getDate());
                     vars.put("location", assurance.getLocation());
                     }
                     vars.put("date", assurance.getDate());
                     vars.put("location", assurance.getLocation());
index 4a91eefa19a725af73a518bddf6875a0077ad5fa..ab8516322f55329dca22660ab8e3544e971e979b 100644 (file)
@@ -6,6 +6,7 @@
 <td><?=_Id?></td>
 <td><?=_Date?></td>
 <td><?=$verb?></td>
 <td><?=_Id?></td>
 <td><?=_Date?></td>
 <td><?=$verb?></td>
+<td><?=_Verified Name?></td>
 <td><?=_Points?></td>
 <td><?=_Location?></td>
 <td><?=_Method?></td>
 <td><?=_Points?></td>
 <td><?=_Location?></td>
 <td><?=_Method?></td>
@@ -15,6 +16,9 @@
 <td><?=$id?></td>
 <td><?=$date?></td>
 <td><?=$verbVal?></td>
 <td><?=$id?></td>
 <td><?=$date?></td>
 <td><?=$verbVal?></td>
+<? if($myName) { ?>
+<td><?=$myName?></td>
+<? } ?>
 <td><?=$points?></td>
 <td><?=$location?></td>
 <td><?=$method?></td>
 <td><?=$points?></td>
 <td><?=$location?></td>
 <td><?=$method?></td>
diff --git a/src/org/cacert/gigi/output/NameInput.java b/src/org/cacert/gigi/output/NameInput.java
new file mode 100644 (file)
index 0000000..5eeba5e
--- /dev/null
@@ -0,0 +1,109 @@
+package org.cacert.gigi.output;
+
+import java.io.PrintWriter;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.cacert.gigi.GigiApiException;
+import org.cacert.gigi.dbObjects.Name;
+import org.cacert.gigi.dbObjects.NamePart;
+import org.cacert.gigi.dbObjects.NamePart.NamePartType;
+import org.cacert.gigi.dbObjects.User;
+import org.cacert.gigi.localisation.Language;
+import org.cacert.gigi.output.template.Outputable;
+import org.cacert.gigi.output.template.Template;
+
+public class NameInput implements Outputable {
+
+    private static final Template t = new Template(NameInput.class.getResource("NameInput.templ"));
+
+    private String fname = "";
+
+    private String lname = "";
+
+    private String suffix = "";
+
+    private String name = "";
+
+    public NameInput() {}
+
+    public void update(HttpServletRequest req) throws GigiApiException {
+        fname = req.getParameter("fname");
+        lname = req.getParameter("lname");
+        suffix = req.getParameter("suffix");
+        name = req.getParameter("name");
+        if (fname == null) {
+            fname = "";
+        }
+        if (lname == null) {
+            lname = "";
+        }
+        if (suffix == null) {
+            suffix = "";
+        }
+        if (name == null) {
+            name = "";
+        }
+        if (name != null && name.contains(" ")) {
+            throw new GigiApiException("Single names may only have one part.");
+        }
+
+    }
+
+    @Override
+    public void output(PrintWriter out, Language l, Map<String, Object> vars) {
+        vars.put("fname", fname);
+        vars.put("lname", lname);
+        vars.put("suffix", suffix);
+        vars.put("name", name);
+        t.output(out, l, vars);
+    }
+
+    public void createName(User u) throws GigiApiException {
+        new Name(u, getNameParts());
+    }
+
+    public NamePart[] getNameParts() throws GigiApiException {
+        if (name != null && !name.isEmpty()) {
+            return new NamePart[] {
+                    new NamePart(NamePartType.SINGLE_NAME, name)
+            };
+        }
+        String[] fparts = split(fname);
+        String[] lparts = split(lname);
+        String[] suff = split(suffix);
+        if (fparts.length == 0 || fparts[0].equals("") || lparts.length == 0 || lparts[0].equals("")) {
+            throw new GigiApiException("requires at least one first and one last name");
+        }
+        NamePart[] np = new NamePart[fparts.length + lparts.length + suff.length];
+        int p = 0;
+        for (int i = 0; i < fparts.length; i++) {
+            np[p++] = new NamePart(NamePartType.FIRST_NAME, fparts[i]);
+        }
+        for (int i = 0; i < lparts.length; i++) {
+            np[p++] = new NamePart(NamePartType.LAST_NAME, lparts[i]);
+        }
+        for (int i = 0; i < suff.length; i++) {
+            np[p++] = new NamePart(NamePartType.SUFFIX, suff[i]);
+        }
+
+        return np;
+    }
+
+    private String[] split(String toSplit) {
+        if (toSplit == null || toSplit.trim().isEmpty()) {
+            return new String[0];
+        }
+        return toSplit.split(" ");
+    }
+
+    public String[] getNamePartsPlain() throws GigiApiException {
+        NamePart[] p = getNameParts();
+        String[] s = new String[p.length];
+        for (int i = 0; i < s.length; i++) {
+            s[i] = p[i].getValue();
+        }
+        return s;
+    }
+}
diff --git a/src/org/cacert/gigi/output/NameInput.templ b/src/org/cacert/gigi/output/NameInput.templ
new file mode 100644 (file)
index 0000000..2cb11fc
--- /dev/null
@@ -0,0 +1,24 @@
+<h3><?=_First-Last-Suffix Name?></h3>
+<h4><?=_Structure?></h4>
+<?=_Name consists of one or more first names, one or more last names and any amount of suffixes?>
+<h4><?=_Variant Generation?></h4>
+<ul>
+<li><?=_First names may be swapped?></li>
+<li><?=_The first Last Name is mandatory, any other ones may be omitted, but must stay in sequence.?></li>
+<li><?=_Any Suffixes may be omitted, but must stay in sequence.?></li>
+</ul>
+<div>
+<input type='text' name='fname' class="form-control" placeholder="<?=_First Names?>" value="<?=$fname?>">
+<input type='text' name='lname' class="form-control" placeholder="<?=_Last Names?>" value="<?=$lname?>">
+<input type='text' name='suffix' class="form-control" placeholder="<?=_Suffixes?>" value="<?=$suffix?>">
+</div>
+<h3><?=_Single Name?></h3>
+<h4><?=_Structure?></h4>
+<?=_Name of one part?>
+<h4><?=_Variant Generation?></h4>
+<ul>
+<li><?=_Name has no variants?></li>
+</ul>
+<div>
+<input type='text' name='name' class="form-control" placeholder="<?=_Name?>" value="<?=$name?>">
+</div>
\ No newline at end of file
index 4b0aa992fe6025bac5ed46c834a96fef62958acc..bf80d47beaf53fb1197a5f169944342ab04fbe44 100644 (file)
@@ -44,8 +44,10 @@ public class MyDetails extends Page {
 
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
 
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        if (req.getParameter("processDetails") != null) {
-            Form.getForm(req, MyDetailsForm.class).submit(resp.getWriter(), req);
+        if (req.getParameter("action") != null || req.getParameter("removeName") != null || req.getParameter("deprecateName") != null || req.getParameter("preferred") != null) {
+            if (Form.getForm(req, MyDetailsForm.class).submit(resp.getWriter(), req)) {
+                resp.sendRedirect(PATH);
+            }
         }
         super.doPost(req, resp);
     }
         }
         super.doPost(req, resp);
     }
index d35ba45e84bea8ec27872807196abf4de2be6632..2d1f7ff3c9b80ece5271f3729b8c26503d19c18a 100644 (file)
@@ -9,11 +9,12 @@ import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.dbObjects.Name;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.localisation.Language;
 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.output.DateSelector;
 import org.cacert.gigi.output.DateSelector;
+import org.cacert.gigi.output.NameInput;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.Template;
 import org.cacert.gigi.pages.Page;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.Template;
 import org.cacert.gigi.pages.Page;
-import org.cacert.gigi.util.HTMLEncoder;
 
 public class MyDetailsForm extends Form {
 
 
 public class MyDetailsForm extends Form {
 
@@ -21,36 +22,65 @@ public class MyDetailsForm extends Form {
 
     private static final Template templ = new Template(MyDetailsForm.class.getResource("MyDetailsForm.templ"));
 
 
     private static final Template templ = new Template(MyDetailsForm.class.getResource("MyDetailsForm.templ"));
 
+    private static final Template names = new Template(MyDetailsForm.class.getResource("NamesForm.templ"));
+
     private User target;
 
     private DateSelector ds;
 
     private User target;
 
     private DateSelector ds;
 
+    private NameInput ni;
+
     public MyDetailsForm(HttpServletRequest hsr, User target) {
         super(hsr);
         this.target = target;
     public MyDetailsForm(HttpServletRequest hsr, User target) {
         super(hsr);
         this.target = target;
+        ni = new NameInput();
+
         this.ds = new DateSelector("day", "month", "year", target.getDoB());
     }
 
     @Override
     public boolean submit(PrintWriter out, HttpServletRequest req) {
         try {
         this.ds = new DateSelector("day", "month", "year", target.getDoB());
     }
 
     @Override
     public boolean submit(PrintWriter out, HttpServletRequest req) {
         try {
-            synchronized (target) {
-                if (target.getAssurancePoints() == 0) {
-                    String newFname = req.getParameter("fname").trim();
-                    String newLname = req.getParameter("lname").trim();
-                    String newMname = req.getParameter("mname").trim();
-                    String newSuffix = req.getParameter("suffix").trim();
-                    if (newLname.isEmpty()) {
-                        throw new GigiApiException("Last name cannot be empty.");
-                    }
-
-                    target.setName(new Name(newFname, newLname, newMname, newSuffix));
-                    ds.update(req);
-                    target.setDoB(ds.getDate());
-                    target.updateUserData();
-                } else {
-                    throw new GigiApiException("No change after assurance allowed.");
+            String rn = req.getParameter("removeName");
+            if (rn != null) {
+                Name n = Name.getById(Integer.parseInt(rn));
+                if (n.getOwner() != target) {
+                    throw new GigiApiException("Cannot remove a name that does not belong to this account.");
                 }
                 }
+                if (n.equals(target.getPreferredName())) {
+                    throw new GigiApiException("Cannot remove the account's preferred name.");
+                }
+                n.remove();
+                return true;
+            }
+            String dn = req.getParameter("deprecateName");
+            if (dn != null) {
+                Name n = Name.getById(Integer.parseInt(dn));
+                if (n.getOwner() != target) {
+                    throw new GigiApiException("Cannot deprecate a name that does not belong to this account.");
+                }
+                if (n.equals(target.getPreferredName())) {
+                    throw new GigiApiException("Cannot deprecate the account's preferred name.");
+                }
+                n.deprecate();
+                return true;
+            }
+            String pn = req.getParameter("preferred");
+            if (pn != null) {
+                Name n = Name.getById(Integer.parseInt(pn));
+                target.setPreferredName(n);
+                return true;
+            }
+
+            String action = req.getParameter("action");
+            if ("addName".equals(action)) {
+                ni.update(req);
+                ni.createName(target);
+                return true;
+            }
+            if ("updateDoB".equals(action)) {
+                ds.update(req);
+                target.setDoB(ds.getDate());
             }
         } catch (GigiApiException e) {
             e.format(out, Page.getLanguage(req));
             }
         } catch (GigiApiException e) {
             e.format(out, Page.getLanguage(req));
@@ -64,12 +94,31 @@ public class MyDetailsForm extends Form {
 
     @Override
     protected void outputContent(PrintWriter out, Language l, Map<String, Object> vars) {
 
     @Override
     protected void outputContent(PrintWriter out, Language l, Map<String, Object> vars) {
-        Name name = target.getName();
-        vars.put("fname", HTMLEncoder.encodeHTML(name.getFname()));
-        vars.put("mname", name.getMname() == null ? "" : HTMLEncoder.encodeHTML(name.getMname()));
-        vars.put("lname", HTMLEncoder.encodeHTML(name.getLname()));
-        vars.put("suffix", name.getSuffix() == null ? "" : HTMLEncoder.encodeHTML(name.getSuffix()));
-        vars.put("details", "");
+        vars.put("exNames", new ArrayIterable<Name>(target.getNames()) {
+
+            Name preferred = target.getPreferredName();
+
+            @Override
+            public void apply(Name t, Language l, Map<String, Object> vars) {
+                if (t.equals(preferred)) {
+                    vars.put("preferred", " disabled");
+                    vars.put("deprecated", " disabled");
+                } else {
+                    if (t.isDeprecated()) {
+                        vars.put("deprecated", " disabled");
+                    } else {
+                        vars.put("deprecated", "");
+                    }
+                    vars.put("preferred", "");
+                }
+                vars.put("name", t);
+                vars.put("id", t.getId());
+                vars.put("npoints", Integer.toString(t.getAssurancePoints()));
+            }
+
+        });
+        vars.put("name", ni);
+        names.output(out, l, vars);
         if (target.getAssurancePoints() == 0) {
             vars.put("DoB", ds);
             templ.output(out, l, vars);
         if (target.getAssurancePoints() == 0) {
             vars.put("DoB", ds);
             templ.output(out, l, vars);
index d4d3c7e0cee9f7f0f452fe606a02c6853dcf2f25..f9ea0c7244dea6318741f4bb331356878dea68ee 100644 (file)
@@ -1,42 +1,13 @@
 <table class="table">
 <table class="table">
-<thead>
-  <tr>
-    <th colspan="2"><?=_My Details?></th>
-  </tr>
-  </thead>
   <tbody>
   <tbody>
-  <tr>
-    <td><?=_First Name?>: </td>
-    <td><input class="form-control" type="text" name="fname" value="<?=$fname?>"></td>
-  </tr>
-  <tr>
-    <td valign="top"><?=_Middle Name(s)?><br>
-      (<?=_optional?>)
-    </td>
-    <td><input class="form-control" type="text" name="mname" value="<?=$mname?>"></td>
-  </tr>
-  <tr>
-    <td><?=_Last Name?>: </td>
-    <td><input class="form-control" type="text" name="lname" value="<?=$lname?>"></td>
-  </tr>
-  <tr>
-    <td><?=_Suffix?><br>
-      (<?=_optional?>)</td>
-    <td><input class="form-control" type="text" name="suffix" value="<?=$suffix?>"></td>
-  </tr>
   <tr>
     <td><?=_Date of Birth?><br>
            (<?=_yyyy-mm-dd?>)</td>
     <td><?=$DoB?></td>
   <tr>
     <td><?=_Date of Birth?><br>
            (<?=_yyyy-mm-dd?>)</td>
     <td><?=$DoB?></td>
+    <td><button class="btn btn-primary" name="action" value="updateDoB"><?=_Update Date of Birth?></button></td>
   </tr>
   <tr>
   </tr>
   <tr>
-    <td colspan="2" class="title"><a href="/account/history"><?=_Show account history?></a></td>
-  </tr>
-  <tr>
-    <td colspan="2" class="title"><?=_View secret question & answers and OTP phrases?></td>
-  </tr>
-  <?=$details?>
-  <tr><td colspan="2"><input type="submit" name="processDetails" value="<?=_Update?>"></td>
+    <td colspan="3" class="title"><a href="/account/history"><?=_Show account history?></a></td>
   </tr>
   </tbody>
 </table>
   </tr>
   </tbody>
 </table>
index 8cfb7705bd017edc39ce3bc75d1b7f08f383dfa1..8dde8c3c6f34aee549d953d2956e5e50e5a6743b 100644 (file)
@@ -1,29 +1,5 @@
 <table class="table">
 <table class="table">
-<thead>
-  <tr>
-    <th colspan="2"><?=_My Details?></th>
-  </tr>
-  </thead>
   <tbody>
   <tbody>
-  <tr>
-    <td><?=_First Name?>: </td>
-    <td><?=$fname?></td>
-  </tr>
-  <tr>
-    <td valign="top"><?=_Middle Name(s)?><br>
-      (<?=_optional?>)
-    </td>
-    <td><?=$mname?></td>
-  </tr>
-  <tr>
-    <td><?=_Last Name?>: </td>
-    <td><?=$lname?></td>
-  </tr>
-  <tr>
-    <td><?=_Suffix?><br>
-      (<?=_optional?>)</td>
-    <td><?=$suffix?></td>
-  </tr>
   <tr>
     <td><?=_Date of Birth?><br>
            (<?=_yyyy-mm-dd?>)</td>
   <tr>
     <td><?=_Date of Birth?><br>
            (<?=_yyyy-mm-dd?>)</td>
@@ -32,9 +8,5 @@
   <tr>
     <td colspan="2" class="title"><a href="/account/history"><?=_Show account history?></a></td>
   </tr>
   <tr>
     <td colspan="2" class="title"><a href="/account/history"><?=_Show account history?></a></td>
   </tr>
-  <tr>
-    <td colspan="2" class="title"><?=_View secret question & answers and OTP phrases?></td>
-  </tr>
-  <?=$details?>
   </tbody>
 </table>
   </tbody>
 </table>
diff --git a/src/org/cacert/gigi/pages/account/NamesForm.templ b/src/org/cacert/gigi/pages/account/NamesForm.templ
new file mode 100644 (file)
index 0000000..1ca468d
--- /dev/null
@@ -0,0 +1,19 @@
+<table class="table">
+  <tbody>
+  <? foreach($exNames) { ?>
+  <tr>
+    <td><?=_Name?>: </td>
+    <td><?=$name?></td>
+    <td><?=$npoints?></td>
+    <td><button class="btn btn-warning" name="deprecateName" value="<?=$id?>" type="submit"<?=$deprecated?>><?=_Deprecate Name?></button></td>
+    <td><button class="btn btn-danger" name="removeName" value="<?=$id?>" type="submit"<?=$preferred?>><?=_Remove Name?></button></td>
+    <td><button class="btn btn-primary" name="preferred" value="<?=$id?>" type="submit"<?=$preferred?>><?=_Set as Preferred?></button></td>
+  </tr>
+  <? } ?>
+  <tr>
+    <td><?=_Name?>: </td>
+    <td colspan="5"><?=$name?>
+    <button class="btn btn-primary" name="action" value="addName" type="submit"><?=_Add Name?></button></td>
+  </tr>
+  </tbody>
+</table>
index 2baf95e86ae6b9671b7497a0f392993aa226b2fd..12b6323d2c185a1b86f0305bc43ac7312c5594e1 100644 (file)
@@ -497,7 +497,7 @@ public class CertificateRequest {
                     if (nullIsOK) {
                         name = "";
                     } else if (realIsOK) {
                     if (nullIsOK) {
                         name = "";
                     } else if (realIsOK) {
-                        name = u.getName().toString();
+                        name = u.getPreferredName().toString();
                     }
                 }
             } else if (name == null || name.equals("")) {
                     }
                 }
             } else if (name == null || name.equals("")) {
@@ -508,7 +508,7 @@ public class CertificateRequest {
                     if (defaultIsOK) {
                         name = DEFAULT_CN;
                     } else if (realIsOK) {
                     if (defaultIsOK) {
                         name = DEFAULT_CN;
                     } else if (realIsOK) {
-                        name = u.getName().toString();
+                        name = u.getPreferredName().toString();
                     }
                 }
             } else {
                     }
                 }
             } else {
index 2c8b5719b3d30d570fcab43979785f3d1411306e..ce6eecb3bc6249d7b2b4ba47f56ada7eff185b34 100644 (file)
@@ -36,7 +36,7 @@ public class TTPAdminForm extends Form {
 
     @Override
     protected void outputContent(PrintWriter out, Language l, Map<String, Object> vars) {
 
     @Override
     protected void outputContent(PrintWriter out, Language l, Map<String, Object> vars) {
-        vars.put("name", u.getName());
+        vars.put("name", u.getPreferredName());
         vars.put("email", u.getEmail());
         vars.put("DoB", u.getDoB());
         vars.put("uid", Integer.toString(u.getId()));
         vars.put("email", u.getEmail());
         vars.put("DoB", u.getDoB());
         vars.put("uid", Integer.toString(u.getId()));
index a6bd0d47308a1d0972b52357e5e7a9dbc9e070f4..2ffd12e2085882175260683572bb7c815230452d 100644 (file)
@@ -74,7 +74,7 @@ public class TTPAdminPage extends Page {
                     return false;
                 }
                 vars.put("id", Integer.toString(users[i].getId()));
                     return false;
                 }
                 vars.put("id", Integer.toString(users[i].getId()));
-                vars.put("name", users[i].getName().toString());
+                vars.put("name", users[i].getPreferredName().toString());
                 vars.put("email", users[i].getEmail());
 
                 i++;
                 vars.put("email", users[i].getEmail());
 
                 i++;
index 75173e06a8ff6534b22fbad327a947cce88cb742..16ece06789d6c7be0f20477420b062bbe706fa79 100644 (file)
@@ -13,6 +13,7 @@ import org.cacert.gigi.dbObjects.Name;
 import org.cacert.gigi.dbObjects.SupportedUser;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.dbObjects.SupportedUser;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.localisation.Language;
+import org.cacert.gigi.output.ArrayIterable;
 import org.cacert.gigi.output.DateSelector;
 import org.cacert.gigi.output.GroupSelector;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.DateSelector;
 import org.cacert.gigi.output.GroupSelector;
 import org.cacert.gigi.output.template.Form;
@@ -76,22 +77,11 @@ public class SupportUserDetailsForm extends Form {
             return true;
         }
         dobSelector.update(req);
             return true;
         }
         dobSelector.update(req);
-        String fname = req.getParameter("fname");
-        String mname = req.getParameter("mname");
-        String lname = req.getParameter("lname");
-        String suffix = req.getParameter("suffix");
-        if (fname == null || mname == null || lname == null | suffix == null) {
-            throw new GigiApiException("Incomplete request!");
-        }
         if ( !dobSelector.isValid()) {
             throw new GigiApiException("Invalid date of birth!");
         }
         if ( !dobSelector.isValid()) {
             throw new GigiApiException("Invalid date of birth!");
         }
-        Name newName = new Name(fname, lname, mname, suffix);
-        synchronized (user.getTargetUser()) {
-            if (user.setDob(dobSelector.getDate()) | user.setName(newName)) {
-                user.submitSupportAction();
-            }
-        }
+        user.setDob(dobSelector.getDate());
+
         String subject = "Change Account Data";
         Outputable message = new TranslateCommand("The account data was changed.");
         user.sendSupportNotification(subject, message);
         String subject = "Change Account Data";
         Outputable message = new TranslateCommand("The account data was changed.");
         user.sendSupportNotification(subject, message);
@@ -101,12 +91,16 @@ public class SupportUserDetailsForm extends Form {
     @Override
     protected void outputContent(PrintWriter out, Language l, Map<String, Object> vars) {
         User user = this.user.getTargetUser();
     @Override
     protected void outputContent(PrintWriter out, Language l, Map<String, Object> vars) {
         User user = this.user.getTargetUser();
-        Name name = user.getName();
         vars.put("mail", user.getEmail());
         vars.put("mail", user.getEmail());
-        vars.put("fname", name.getFname());
-        vars.put("mname", name.getMname());
-        vars.put("lname", name.getLname());
-        vars.put("suffix", name.getSuffix());
+        vars.put("exNames", new ArrayIterable<Name>(user.getNames()) {
+
+            @Override
+            public void apply(Name t, Language l, Map<String, Object> vars) {
+                vars.put("name", t);
+                vars.put("points", Integer.toString(t.getAssurancePoints()));
+            }
+
+        });
         vars.put("assurer", user.canAssure());
         vars.put("dob", dobSelector);
         vars.put("assurancepoints", user.getAssurancePoints());
         vars.put("assurer", user.canAssure());
         vars.put("dob", dobSelector);
         vars.put("assurancepoints", user.getAssurancePoints());
index c4f52d0ece886d911a3922bb31a403aab343fe91..06dbd0423ae9410f8b79f2421364e9bf1758efc4 100644 (file)
@@ -6,26 +6,12 @@
             <td><?=_Email?>:</td>
             <td><?=$mail?></td>
         </tr>
             <td><?=_Email?>:</td>
             <td><?=$mail?></td>
         </tr>
+  <? foreach($exNames) { ?>
         <tr>
         <tr>
-            <td><?=_First Name?>:</td>
-            <td>
-                <input class="form-control" type="text" value="<?=$fname?>" name="fname">
-           </td>
-        </tr>
-        <tr>
-            <td><?=_Middle Name?>:</td>
-            <td><input class="form-control" type="text" value="<?=$mname?>" name="mname"></td>
-        </tr>
-        <tr>
-            <td><?=_Last Name?>:</td>
-            <td>
-                <input class="form-control" type="text" value="<?=$lname?>" name="lname">
-            </td>
-        </tr>
-        <tr>
-            <td><?=_Suffix?>:</td>
-            <td><input class="form-control" type="text" value="<?=$suffix?>" name="suffix"></td>
+          <td><?=_Name?>: </td>
+          <td><?=$name?> (<?=$points?>)</td>
         </tr>
         </tr>
+  <? } ?>
         <tr>
             <td><?=_Date of Birth?>:</td>
             <td>
         <tr>
             <td><?=_Date of Birth?>:</td>
             <td>
index 0fc04d8e9f9144e3202b956ef009bc74a3cab31b..7cc389e72e2ac2b249c0b4c78773cdc5a8f3d04a 100644 (file)
@@ -10,11 +10,11 @@ import javax.servlet.http.HttpServletRequest;
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.database.GigiPreparedStatement;
 import org.cacert.gigi.database.GigiResultSet;
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.database.GigiPreparedStatement;
 import org.cacert.gigi.database.GigiResultSet;
-import org.cacert.gigi.dbObjects.Name;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.email.EmailProvider;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.DateSelector;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.email.EmailProvider;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.DateSelector;
+import org.cacert.gigi.output.NameInput;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.PlainOutputable;
 import org.cacert.gigi.output.template.SprintfCommand;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.PlainOutputable;
 import org.cacert.gigi.output.template.SprintfCommand;
@@ -28,28 +28,25 @@ import org.cacert.gigi.util.RateLimit.RateLimitException;
 
 public class Signup extends Form {
 
 
 public class Signup extends Form {
 
-    Name buildupName = new Name("", "", "", "");
+    private NameInput ni;
 
 
-    String email = "";
+    private String email = "";
 
     private static final Template t = new Template(Signup.class.getResource("Signup.templ"));
 
 
     private static final Template t = new Template(Signup.class.getResource("Signup.templ"));
 
-    boolean general = true, country = true, regional = true, radius = true;
+    private boolean general = true, country = true, regional = true, radius = true;
 
     public Signup(HttpServletRequest hsr) {
         super(hsr);
 
     public Signup(HttpServletRequest hsr) {
         super(hsr);
-
+        ni = new NameInput();
     }
 
     }
 
-    DateSelector myDoB = new DateSelector("day", "month", "year");
+    private DateSelector myDoB = new DateSelector("day", "month", "year");
 
     @Override
     public void outputContent(PrintWriter out, Language l, Map<String, Object> outerVars) {
         HashMap<String, Object> vars = new HashMap<String, Object>();
 
     @Override
     public void outputContent(PrintWriter out, Language l, Map<String, Object> outerVars) {
         HashMap<String, Object> vars = new HashMap<String, Object>();
-        vars.put("fname", HTMLEncoder.encodeHTML(buildupName.getFname()));
-        vars.put("mname", HTMLEncoder.encodeHTML(buildupName.getMname()));
-        vars.put("lname", HTMLEncoder.encodeHTML(buildupName.getLname()));
-        vars.put("suffix", HTMLEncoder.encodeHTML(buildupName.getSuffix()));
+        vars.put("name", ni);
         vars.put("dob", myDoB);
         vars.put("email", HTMLEncoder.encodeHTML(email));
         vars.put("general", general ? " checked=\"checked\"" : "");
         vars.put("dob", myDoB);
         vars.put("email", HTMLEncoder.encodeHTML(email));
         vars.put("general", general ? " checked=\"checked\"" : "");
@@ -62,27 +59,11 @@ public class Signup extends Form {
         t.output(out, l, vars);
     }
 
         t.output(out, l, vars);
     }
 
-    private void update(HttpServletRequest r) {
-        String fname = buildupName.getFname();
-        String lname = buildupName.getLname();
-        String mname = buildupName.getMname();
-        String suffix = buildupName.getSuffix();
-        if (r.getParameter("fname") != null) {
-            fname = r.getParameter("fname");
-        }
-        if (r.getParameter("lname") != null) {
-            lname = r.getParameter("lname");
-        }
-        if (r.getParameter("mname") != null) {
-            mname = r.getParameter("mname");
-        }
-        if (r.getParameter("suffix") != null) {
-            suffix = r.getParameter("suffix");
-        }
+    private void update(HttpServletRequest r) throws GigiApiException {
+        ni.update(r);
         if (r.getParameter("email") != null) {
             email = r.getParameter("email");
         }
         if (r.getParameter("email") != null) {
             email = r.getParameter("email");
         }
-        buildupName = new Name(fname, lname, mname, suffix);
         general = "1".equals(r.getParameter("general"));
         country = "1".equals(r.getParameter("country"));
         regional = "1".equals(r.getParameter("regional"));
         general = "1".equals(r.getParameter("general"));
         country = "1".equals(r.getParameter("country"));
         regional = "1".equals(r.getParameter("regional"));
@@ -101,9 +82,12 @@ public class Signup extends Form {
 
         update(req);
         GigiApiException ga = new GigiApiException();
 
         update(req);
         GigiApiException ga = new GigiApiException();
-        if (buildupName.getLname().trim().equals("")) {
-            ga.mergeInto(new GigiApiException("Last name were blank."));
+        try {
+            ni.getNameParts();
+        } catch (GigiApiException e) {
+            ga.mergeInto(e);
         }
         }
+
         if ( !myDoB.isValid()) {
             ga.mergeInto(new GigiApiException("Invalid date of birth"));
         }
         if ( !myDoB.isValid()) {
             ga.mergeInto(new GigiApiException("Invalid date of birth"));
         }
@@ -125,7 +109,7 @@ public class Signup extends Form {
         } else if ( !pw1.equals(pw2)) {
             ga.mergeInto(new GigiApiException("Pass Phrases don't match"));
         }
         } else if ( !pw1.equals(pw2)) {
             ga.mergeInto(new GigiApiException("Pass Phrases don't match"));
         }
-        int pwpoints = PasswordStrengthChecker.checkpw(pw1, buildupName, email);
+        int pwpoints = PasswordStrengthChecker.checkpw(pw1, ni.getNamePartsPlain(), email);
         if (pwpoints < 3) {
             ga.mergeInto(new GigiApiException("The Pass Phrase you submitted failed to contain enough" + " differing characters and/or contained words from" + " your name and/or email address."));
         }
         if (pwpoints < 3) {
             ga.mergeInto(new GigiApiException("The Pass Phrase you submitted failed to contain enough" + " differing characters and/or contained words from" + " your name and/or email address."));
         }
@@ -177,7 +161,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, buildupName, myDoB.getDate(), Page.getLanguage(req).getLocale());
+        User u = new User(email, password, myDoB.getDate(), Page.getLanguage(req).getLocale(), 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());
index 59e22cd4ceffa9ded2c00de750ad2733256e2fa1..c47bf8f1a7d8921eb8651f8adad8c38e423a5b73 100644 (file)
@@ -6,29 +6,10 @@
   </thead>
   <tbody>
   <tr>
   </thead>
   <tbody>
   <tr>
-    <td><?=_First Name?>: </td>
-    <td><input class="form-control" type="text" name="fname" size="30" value="<?=$fname?>" autocomplete="off"></td>
+    <td><?=_Name?>: </td>
+    <td><?=$name?></td>
     <td rowspan="4"><?=$!helpOnNames?></td>
   </tr>
     <td rowspan="4"><?=$!helpOnNames?></td>
   </tr>
-
-  <tr>
-    <td><?=_Middle Name(s)?><br>
-      (<?=_optional?>)
-    </td>
-    <td><input class="form-control" type="text" name="mname" size="30" value="<?=$mname?>" autocomplete="off"></td>
-  </tr>
-
-  <tr>
-    <td><?=_Last Name?>: </td>
-    <td><input class="form-control" type="text" name="lname" size="30" value="<?=$lname?>" autocomplete="off"></td>
-  </tr>
-
-  <tr>
-    <td><?=_Suffix?><br>
-      (<?=_optional?>)</td>
-    <td><input class="form-control" type="text" name="suffix" size="30" value="<?=$suffix?>" autocomplete="off"><br><?=_Please only write Name Suffixes into this field.?></td>
-  </tr>
-
   <tr>
     <td><?=_Date of Birth (minimum age: ${dobmin} years)?><br>
            (<?=_yyyy-mm-dd?>)</td>
   <tr>
     <td><?=_Date of Birth (minimum age: ${dobmin} years)?><br>
            (<?=_yyyy-mm-dd?>)</td>
index f6a2da7d1af0392ca27ea94c3aa3d6eabb6e8029..6ffc8822d142ace91992f4b171ede427bb72e338 100644 (file)
@@ -63,7 +63,7 @@ public class AffiliationForm extends Form {
                     return false;
                 }
                 Affiliation aff = iter.next();
                     return false;
                 }
                 Affiliation aff = iter.next();
-                vars.put("name", aff.getTarget().getName());
+                vars.put("name", aff.getTarget().getPreferredName());
                 vars.put("master", aff.isMaster() ? l.getTranslation("master") : "");
                 vars.put("e-mail", aff.getTarget().getEmail());
                 return true;
                 vars.put("master", aff.isMaster() ? l.getTranslation("master") : "");
                 vars.put("e-mail", aff.getTarget().getEmail());
                 return true;
index 07a0fdc22d11746e72741867e1afbbab1739cd4e..7d15e8dac5386d25b7179df81805c97ad8a5e1c2 100644 (file)
@@ -2,7 +2,9 @@ package org.cacert.gigi.pages.wot;
 
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
 
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Map;
@@ -14,8 +16,10 @@ import org.cacert.gigi.dbObjects.Assurance.AssuranceType;
 import org.cacert.gigi.dbObjects.Name;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.localisation.Language;
 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.output.template.Form;
 import org.cacert.gigi.output.template.IterableDataset;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.IterableDataset;
+import org.cacert.gigi.output.template.SprintfCommand;
 import org.cacert.gigi.output.template.Template;
 import org.cacert.gigi.pages.Page;
 import org.cacert.gigi.pages.PasswordResetPage;
 import org.cacert.gigi.output.template.Template;
 import org.cacert.gigi.pages.Page;
 import org.cacert.gigi.pages.PasswordResetPage;
@@ -26,7 +30,9 @@ public class AssuranceForm extends Form {
 
     private User assuree;
 
 
     private User assuree;
 
-    private Name assureeName;
+    private Name[] assureeNames;
+
+    private boolean[] selected;
 
     private DayDate dob;
 
 
     private DayDate dob;
 
@@ -42,12 +48,31 @@ public class AssuranceForm extends Form {
 
     private static final Template templ = new Template(AssuranceForm.class.getResource("AssuranceForm.templ"));
 
 
     private static final Template templ = new Template(AssuranceForm.class.getResource("AssuranceForm.templ"));
 
-    public AssuranceForm(HttpServletRequest hsr, User assuree) {
+    public AssuranceForm(HttpServletRequest hsr, User assuree) throws GigiApiException {
         super(hsr);
         assurer = Page.getUser(hsr);
         this.assuree = assuree;
         super(hsr);
         assurer = Page.getUser(hsr);
         this.assuree = assuree;
-        assureeName = this.assuree.getName();
+
+        if (assurer.getId() == assuree.getId()) {
+            throw new GigiApiException("You cannot verify yourself.");
+        }
+        if ( !assurer.canAssure()) {
+            throw new GigiApiException("You are not a RA-Agent.");
+        }
+
+        Name[] initialNames = this.assuree.getNonDeprecatedNames();
+        LinkedList<Name> names = new LinkedList<>();
+        for (Name name : initialNames) {
+            if (Notary.checkAssuranceIsPossible(assurer, name)) {
+                names.add(name);
+            }
+        }
+        if (names.size() == 0) {
+            throw new GigiApiException(SprintfCommand.createSimple("You have already verified all names of this applicant within the last {0} days.", Notary.LIMIT_DAYS_VERIFICATION));
+        }
+        assureeNames = names.toArray(new Name[names.size()]);
         dob = this.assuree.getDoB();
         dob = this.assuree.getDoB();
+        selected = new boolean[assureeNames.length];
     }
 
     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
     }
 
     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
@@ -58,8 +83,17 @@ public class AssuranceForm extends Form {
     public void outputContent(PrintWriter out, Language l, Map<String, Object> vars) {
         HashMap<String, Object> res = new HashMap<String, Object>();
         res.putAll(vars);
     public void outputContent(PrintWriter out, Language l, Map<String, Object> vars) {
         HashMap<String, Object> res = new HashMap<String, Object>();
         res.putAll(vars);
-        res.put("nameExplicit", assuree.getName());
-        res.put("name", assuree.getName().toString());
+        res.put("names", new ArrayIterable<Name>(assureeNames) {
+
+            @Override
+            public void apply(Name t, Language l, Map<String, Object> vars) {
+                vars.put("nameExplicit", t);
+                vars.put("nameId", t.getId());
+                vars.put("checked", selected[i] ? " checked" : "");
+            }
+
+        });
+        res.put("name", assuree.getPreferredName().toString());
         res.put("maxpoints", assurer.getMaxAssurePoints());
         res.put("dob", sdf.format(assuree.getDoB().toDate()));
         res.put("dobFmt2", sdf2.format(assuree.getDoB().toDate()));
         res.put("maxpoints", assurer.getMaxAssurePoints());
         res.put("dob", sdf.format(assuree.getDoB().toDate()));
         res.put("dobFmt2", sdf2.format(assuree.getDoB().toDate()));
@@ -133,11 +167,19 @@ public class AssuranceForm extends Form {
                 gae.mergeInto(new GigiApiException("The points entered were not a number."));
             }
         }
                 gae.mergeInto(new GigiApiException("The points entered were not a number."));
             }
         }
+        HashSet<String> data = new HashSet<>(Arrays.asList(req.getParameterValues("assuredName")));
+        for (int i = 0; i < assureeNames.length; i++) {
+            selected[i] = data.contains(Integer.toString(assureeNames[i].getId()));
+        }
 
         if ( !gae.isEmpty()) {
             throw gae;
         }
 
         if ( !gae.isEmpty()) {
             throw gae;
         }
-        Notary.assure(assurer, assuree, assureeName, dob, pointsI, location, req.getParameter("date"), type);
+        for (int i = 0; i < selected.length; i++) {
+            if (selected[i]) {
+                Notary.assure(assurer, assuree, assureeNames[i], dob, pointsI, location, req.getParameter("date"), type);
+            }
+        }
         if (aword != null && !aword.equals("")) {
             Language l = Language.getInstance(assuree.getPreferredLocale());
             String method = l.getTranslation("A password reset was triggered. If you did a password reset by assurance, please enter your secret password using this form:");
         if (aword != null && !aword.equals("")) {
             Language l = Language.getInstance(assuree.getPreferredLocale());
             String method = l.getTranslation("A password reset was triggered. If you did a password reset by assurance, please enter your secret password using this form:");
index 5bebe9b761200dfadb97b526a24285c851eaac71..004710aa49c158a53bf5589766719d3e716a23bb 100644 (file)
@@ -5,11 +5,12 @@
 <tbody>
 <tr><td colspan="2"><?=_Please check the following details match against what you witnessed when you met ${name} in person. You MUST NOT proceed unless you are sure the details are correct. You may be held responsible by the SomeCA Arbitrator for any issues with this Verification.?>
 </td></tr>
 <tbody>
 <tr><td colspan="2"><?=_Please check the following details match against what you witnessed when you met ${name} in person. You MUST NOT proceed unless you are sure the details are correct. You may be held responsible by the SomeCA Arbitrator for any issues with this Verification.?>
 </td></tr>
-
+<? foreach($names) { ?>
        <tr>
                <td><?=_Name?>: </td>
        <tr>
                <td><?=_Name?>: </td>
-               <td><span class="accountdetail"><?=$nameExplicit?></span></td>
+               <td><input type="checkbox" name="assuredName" value="<?=$nameId?>"<?=$checked?>><span class="accountdetail"><?=$nameExplicit?></span></td>
        </tr>
        </tr>
+<? } ?>
        <tr>
                <td><?=_Date of Birth?>: </td>
                <td><span class="accountdetail dob"><?=$dob?> (<?=$dobFmt2?>)</span></td>
        <tr>
                <td><?=_Date of Birth?>: </td>
                <td><span class="accountdetail dob"><?=$dob?> (<?=$dobFmt2?>)</span></td>
index 5255cf3248dc1d0905713c385caf1a14a3e59671..8d4a3aacb3259fbccf23c454cbd30cddff68f0a0 100644 (file)
@@ -14,10 +14,8 @@ import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.output.DateSelector;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.Template;
 import org.cacert.gigi.output.DateSelector;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.Template;
-import org.cacert.gigi.pages.LoginPage;
 import org.cacert.gigi.pages.Page;
 import org.cacert.gigi.util.AuthorizationContext;
 import org.cacert.gigi.pages.Page;
 import org.cacert.gigi.util.AuthorizationContext;
-import org.cacert.gigi.util.Notary;
 
 public class AssurePage extends Page {
 
 
 public class AssurePage extends Page {
 
@@ -58,12 +56,7 @@ public class AssurePage extends Page {
                 }
             } catch (GigiApiException e) {
                 e.format(out, Page.getLanguage(req));
                 }
             } catch (GigiApiException e) {
                 e.format(out, Page.getLanguage(req));
-                try {
-                    Notary.checkAssuranceIsPossible(LoginPage.getUser(req), form.getAssuree());
-                    form.output(out, getLanguage(req), new HashMap<String, Object>());
-                } catch (GigiApiException e1) {
-                    e1.format(out, Page.getLanguage(req));
-                }
+                form.output(out, getLanguage(req), new HashMap<String, Object>());
             }
 
             return;
             }
 
             return;
@@ -88,9 +81,7 @@ public class AssurePage extends Page {
 
                     } else {
                         User assuree = User.getById(id);
 
                     } else {
                         User assuree = User.getById(id);
-                        User myself = LoginPage.getUser(req);
                         try {
                         try {
-                            Notary.checkAssuranceIsPossible(myself, assuree);
                             new AssuranceForm(req, assuree).output(out, getLanguage(req), new HashMap<String, Object>());
                         } catch (GigiApiException e) {
                             e.format(out, Page.getLanguage(req));
                             new AssuranceForm(req, assuree).output(out, getLanguage(req), new HashMap<String, Object>());
                         } catch (GigiApiException e) {
                             e.format(out, Page.getLanguage(req));
index a0c654808bba8909f4a55c4dbf8fe2a97081939c..7fdd5c8fd5adb95b9a64c2bb763921593ceb5dfb 100644 (file)
@@ -1,3 +1,4 @@
+<h2><?=_Verification Points You Received?></h2>
 <?=$pointlist?>
 <h2><?=_Verification Points You Issued?></h2>
 <?=$madelist?>
 <?=$pointlist?>
 <h2><?=_Verification Points You Issued?></h2>
 <?=$madelist?>
@@ -6,5 +7,4 @@
 <? if($expP) { ?>
 <?=_Experience points?>: <?=$expP?><br/>
 <?=_Max points to issue?>: <?=$maxP?><br/>
 <? if($expP) { ?>
 <?=_Experience points?>: <?=$expP?><br/>
 <?=_Max points to issue?>: <?=$maxP?><br/>
-
 <? } ?>
 <? } ?>
index dfd591e41fc0450f463a24b3a3ccd5317f94ca8b..8098eeed5aa742cebd3250554098bcb6ffc75ce6 100644 (file)
@@ -75,10 +75,10 @@ public class AuthorizationContext implements Outputable {
             public void output(PrintWriter out, Language l, Map<String, Object> vars) {
                 if (target != actor) {
                     vars.put("user", ((Organisation) target).getName().toString());
             public void output(PrintWriter out, Language l, Map<String, Object> vars) {
                 if (target != actor) {
                     vars.put("user", ((Organisation) target).getName().toString());
-                    vars.put("target", actor.getName().toString());
+                    vars.put("target", actor.getPreferredName().toString());
                     inner.output(out, l, vars);
                 } else {
                     inner.output(out, l, vars);
                 } else {
-                    out.println(actor.getName().toString());
+                    out.println(actor.getPreferredName().toString());
                 }
             }
         });
                 }
             }
         });
index e6288988d5952a4049da2bc0909e6a6a2efbb9bb..0ecc14e444fb3db2e96cdbe886f737d7abb2ec0f 100644 (file)
@@ -31,23 +31,14 @@ public class Notary {
         }
     }
 
         }
     }
 
-    public static void checkAssuranceIsPossible(User assurer, User target) throws GigiApiException {
-        if (assurer.getId() == target.getId()) {
-            throw new GigiApiException("You cannot assure yourself.");
-        }
+    public static boolean checkAssuranceIsPossible(User assurer, Name target) {
         try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT 1 FROM `notary` where `to`=? and `from`=? and `method` = ? ::`notaryType` AND `deleted` IS NULL AND `when` > (now() - interval '1 days' * ?)")) {
             ps.setInt(1, target.getId());
             ps.setInt(2, assurer.getId());
             ps.setString(3, AssuranceType.FACE_TO_FACE.getDescription());
             ps.setInt(4, LIMIT_DAYS_VERIFICATION);
             GigiResultSet rs = ps.executeQuery();
         try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT 1 FROM `notary` where `to`=? and `from`=? and `method` = ? ::`notaryType` AND `deleted` IS NULL AND `when` > (now() - interval '1 days' * ?)")) {
             ps.setInt(1, target.getId());
             ps.setInt(2, assurer.getId());
             ps.setString(3, AssuranceType.FACE_TO_FACE.getDescription());
             ps.setInt(4, LIMIT_DAYS_VERIFICATION);
             GigiResultSet rs = ps.executeQuery();
-            if (rs.next()) {
-                rs.close();
-                throw new GigiApiException(SprintfCommand.createSimple("You have already verified this applicant within the last {0} days.", LIMIT_DAYS_VERIFICATION));
-            }
-        }
-        if ( !assurer.canAssure()) {
-            throw new GigiApiException("You are not an assurer.");
+            return !rs.next();
         }
     }
 
         }
     }
 
@@ -105,16 +96,24 @@ public class Notary {
             gae.mergeInto(new GigiApiException("You must enter a location with at least 3 characters eg town and country."));
         }
         synchronized (assuree) {
             gae.mergeInto(new GigiApiException("You must enter a location with at least 3 characters eg town and country."));
         }
         synchronized (assuree) {
+            if (assurer.getId() == assuree.getId()) {
+                throw new GigiApiException("You cannot verify yourself.");
+            }
+            if (assureeName.getOwner() != assuree) {
+                throw new GigiApiException("Internal error, name does not belong to applicant.");
+            }
+            if ( !assurer.canAssure()) {
+                throw new GigiApiException("You are not an RA-Agent.");
+            }
 
 
-            try {
-                checkAssuranceIsPossible(assurer, assuree);
-            } catch (GigiApiException e) {
-                gae.mergeInto(e);
+            if ( !checkAssuranceIsPossible(assurer, assureeName)) {
+                gae.mergeInto(new GigiApiException(SprintfCommand.createSimple("You have already verified this applicant within the last {0} days.", LIMIT_DAYS_VERIFICATION)));
             }
 
             }
 
-            if ( !assuree.getName().equals(assureeName) || !assuree.getDoB().equals(dob)) {
+            if ( !assuree.getDoB().equals(dob)) {
                 gae.mergeInto(new GigiApiException("The person you are assuring changed his personal details."));
             }
                 gae.mergeInto(new GigiApiException("The person you are assuring changed his personal details."));
             }
+
             if (awarded < 0) {
                 gae.mergeInto(new GigiApiException("The points you are trying to award are out of range."));
             } else {
             if (awarded < 0) {
                 gae.mergeInto(new GigiApiException("The points you are trying to award are out of range."));
             } else {
@@ -134,11 +133,11 @@ public class Notary {
             }
 
             if (type == AssuranceType.FACE_TO_FACE) {
             }
 
             if (type == AssuranceType.FACE_TO_FACE) {
-                assureF2F(assurer, assuree, awarded, location, date);
+                assureF2F(assurer, assuree, assureeName, awarded, location, date);
             } else if (type == AssuranceType.NUCLEUS) {
             } else if (type == AssuranceType.NUCLEUS) {
-                assureNucleus(assurer, assuree, awarded, location, date);
+                assureNucleus(assurer, assuree, assureeName, awarded, location, date);
             } else if (type == AssuranceType.TTP_ASSISTED) {
             } else if (type == AssuranceType.TTP_ASSISTED) {
-                assureTTP(assurer, assuree, awarded, location, date);
+                assureTTP(assurer, assuree, assureeName, awarded, location, date);
             } else {
                 throw new GigiApiException(SprintfCommand.createSimple("Unknown Assurance type: {0}", type.toString()));
             }
             } else {
                 throw new GigiApiException(SprintfCommand.createSimple("Unknown Assurance type: {0}", type.toString()));
             }
@@ -147,11 +146,11 @@ public class Notary {
         }
     }
 
         }
     }
 
-    private static void assureF2F(User assurer, User assuree, int awarded, String location, String date) throws GigiApiException {
+    private static void assureF2F(User assurer, User assuree, Name name, int awarded, String location, String date) throws GigiApiException {
         may(assurer, assuree, AssuranceType.FACE_TO_FACE);
         try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, `points`=?, `location`=?, `date`=?")) {
             ps.setInt(1, assurer.getId());
         may(assurer, assuree, AssuranceType.FACE_TO_FACE);
         try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, `points`=?, `location`=?, `date`=?")) {
             ps.setInt(1, assurer.getId());
-            ps.setInt(2, assuree.getId());
+            ps.setInt(2, name.getId());
             ps.setInt(3, awarded);
             ps.setString(4, location);
             ps.setString(5, date);
             ps.setInt(3, awarded);
             ps.setString(4, location);
             ps.setString(5, date);
@@ -159,11 +158,11 @@ public class Notary {
         }
     }
 
         }
     }
 
-    private static void assureTTP(User assurer, User assuree, int awarded, String location, String date) throws GigiApiException {
+    private static void assureTTP(User assurer, User assuree, Name name, int awarded, String location, String date) throws GigiApiException {
         may(assurer, assuree, AssuranceType.TTP_ASSISTED);
         try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, `points`=?, `location`=?, `date`=?, `method`='TTP-Assisted'")) {
             ps.setInt(1, assurer.getId());
         may(assurer, assuree, AssuranceType.TTP_ASSISTED);
         try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, `points`=?, `location`=?, `date`=?, `method`='TTP-Assisted'")) {
             ps.setInt(1, assurer.getId());
-            ps.setInt(2, assuree.getId());
+            ps.setInt(2, name.getId());
             ps.setInt(3, awarded);
             ps.setString(4, location);
             ps.setString(5, date);
             ps.setInt(3, awarded);
             ps.setString(4, location);
             ps.setString(5, date);
@@ -199,11 +198,11 @@ public class Notary {
         throw new GigiApiException("Verification type not possible.");
     }
 
         throw new GigiApiException("Verification type not possible.");
     }
 
-    private static void assureNucleus(User assurer, User assuree, int awarded, String location, String date) throws GigiApiException {
+    private static void assureNucleus(User assurer, User assuree, Name name, int awarded, String location, String date) throws GigiApiException {
         may(assurer, assuree, AssuranceType.NUCLEUS);
         // Do up to 35 points as f2f
         int f2fPoints = Math.min(assurer.getMaxAssurePoints(), awarded);
         may(assurer, assuree, AssuranceType.NUCLEUS);
         // Do up to 35 points as f2f
         int f2fPoints = Math.min(assurer.getMaxAssurePoints(), awarded);
-        assureF2F(assurer, assuree, f2fPoints, location, date);
+        assureF2F(assurer, assuree, name, f2fPoints, location, date);
 
         awarded -= f2fPoints;
         if (awarded <= 0) {
 
         awarded -= f2fPoints;
         if (awarded <= 0) {
@@ -214,7 +213,7 @@ public class Notary {
         // Valid for 4 Weeks = 28 days
         try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, `points`=?, `location`=?, `date`=?, `method`='Nucleus Bonus', `expire` = CURRENT_TIMESTAMP + interval '28 days'")) {
             ps.setInt(1, assurer.getId());
         // Valid for 4 Weeks = 28 days
         try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, `points`=?, `location`=?, `date`=?, `method`='Nucleus Bonus', `expire` = CURRENT_TIMESTAMP + interval '28 days'")) {
             ps.setInt(1, assurer.getId());
-            ps.setInt(2, assuree.getId());
+            ps.setInt(2, name.getId());
             ps.setInt(3, awarded);
             ps.setString(4, location);
             ps.setString(5, date);
             ps.setInt(3, awarded);
             ps.setString(4, location);
             ps.setString(5, date);
index a1d2145075ceb94b69fef7442fa3588de4977f84..c957665ec667d2da917331b4150c6d23224d3a0b 100644 (file)
@@ -1,9 +1,11 @@
 package org.cacert.gigi.util;
 
 package org.cacert.gigi.util;
 
+import java.util.TreeSet;
 import java.util.regex.Pattern;
 
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.dbObjects.Name;
 import java.util.regex.Pattern;
 
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.dbObjects.Name;
+import org.cacert.gigi.dbObjects.NamePart;
 
 public class PasswordStrengthChecker {
 
 
 public class PasswordStrengthChecker {
 
@@ -51,7 +53,7 @@ public class PasswordStrengthChecker {
         return points;
     }
 
         return points;
     }
 
-    public static int checkpw(String pw, Name name, String email) {
+    public static int checkpw(String pw, String[] nameParts, String email) {
         if (pw == null) {
             return 0;
         }
         if (pw == null) {
             return 0;
         }
@@ -59,24 +61,23 @@ public class PasswordStrengthChecker {
         if (contained(pw, email)) {
             light -= 2;
         }
         if (contained(pw, email)) {
             light -= 2;
         }
-        if (contained(pw, name.getFname())) {
-            light -= 2;
-        }
-        if (contained(pw, name.getLname())) {
-            light -= 2;
-        }
-        if (contained(pw, name.getMname())) {
-            light -= 2;
-        }
-        if (contained(pw, name.getSuffix())) {
-            light -= 2;
+        for (int i = 0; i < nameParts.length; i++) {
+            if (contained(pw, nameParts[i])) {
+                light -= 2;
+            }
         }
         // TODO dictionary check
         return light;
     }
 
         }
         // TODO dictionary check
         return light;
     }
 
-    public static void assertStrongPassword(String pw, Name name, String email) throws GigiApiException {
-        if (checkpw(pw, name, email) < 3) {
+    public static void assertStrongPassword(String pw, Name[] names, String email) throws GigiApiException {
+        TreeSet<String> parts = new TreeSet<>();
+        for (int i = 0; i < names.length; i++) {
+            for (NamePart string : names[i].getParts()) {
+                parts.add(string.getValue());
+            }
+        }
+        if (checkpw(pw, parts.toArray(new String[parts.size()]), email) < 3) {
             throw new GigiApiException("The Pass Phrase you submitted failed to contain enough" + " differing characters and/or contained words from" + " your name and/or email address.");
         }
     }
             throw new GigiApiException("The Pass Phrase you submitted failed to contain enough" + " differing characters and/or contained words from" + " your name and/or email address.");
         }
     }
@@ -93,4 +94,5 @@ public class PasswordStrengthChecker {
         }
         return false;
     }
         }
         return false;
     }
+
 }
 }
index b431166017913ea6688a99033764b7a79ce1be56..ba901a8a2a01cb23aa4cdee5f1fed5c4fd108c94 100644 (file)
@@ -3,42 +3,165 @@ package org.cacert.gigi;
 import static org.junit.Assert.*;
 
 import org.cacert.gigi.dbObjects.Name;
 import static org.junit.Assert.*;
 
 import org.cacert.gigi.dbObjects.Name;
+import org.cacert.gigi.dbObjects.NamePart;
+import org.cacert.gigi.dbObjects.NamePart.NamePartType;
+import org.cacert.gigi.testUtils.ClientBusinessTest;
 import org.junit.Before;
 import org.junit.Test;
 
 import org.junit.Before;
 import org.junit.Test;
 
-public class TestName {
-
-    Name n = new Name("fn", "ln", "mn", "sf");
+public class TestName extends ClientBusinessTest {
 
     @Before
     public void setUp() throws Exception {}
 
     @Test
 
     @Before
     public void setUp() throws Exception {}
 
     @Test
-    public void testHashCode() {
-        assertEquals(new Name("fname", "lname", null, null).hashCode(), new Name("fname", "lname", null, null).hashCode());
-        assertNotEquals(new Name("fname", "lname", null, null).hashCode(), new Name("fname", "lname", null, "b").hashCode());
-        assertNotEquals(new Name("fname", "lname", null, null).hashCode(), new Name("fname", "lname", "b", null).hashCode());
-        assertNotEquals(new Name("fname", "lname", null, null).hashCode(), new Name("fname", "name", null, null).hashCode());
-        assertNotEquals(new Name("fname", "lname", null, null).hashCode(), new Name("name", "lname", null, null).hashCode());
+    public void testNamePartHash() {
+        assertEquals(new NamePart(NamePartType.FIRST_NAME, "f"), new NamePart(NamePartType.FIRST_NAME, "f"));
+        assertNotEquals(new NamePart(NamePartType.FIRST_NAME, "f"), new NamePart(NamePartType.FIRST_NAME, "f2"));
+        assertNotEquals(new NamePart(NamePartType.FIRST_NAME, "f"), new NamePart(NamePartType.LAST_NAME, "f"));
     }
 
     }
 
+    /**
+     * Tests fitness for {@link NamePart#equals(Object)}.
+     */
     @Test
     @Test
-    public void testEqualsObject() {
-        assertFalse(n.equals(null));
-        assertFalse(n.equals("blargh"));
-        Name nullname = new Name(null, null, null, null);
-        assertFalse(n.equals(nullname));
-        assertFalse(nullname.equals(n));
-        assertTrue(nullname.equals(nullname));
-        assertTrue(n.equals(n));
+    public void testNamePartEquals() {
+        NamePart name = new NamePart(NamePartType.FIRST_NAME, "fn");
+        assertFalse(name.equals(null));
+        assertFalse(name.equals("blargh"));
+
+        // namePart that differs in content
+        NamePart diffContent = new NamePart(NamePartType.FIRST_NAME, "f");
+        assertFalse(name.equals(diffContent));
+        assertFalse(diffContent.equals(name));
+        assertTrue(diffContent.equals(diffContent));
+        assertTrue(name.equals(name));
+
+        // name part that is equal
+        NamePart same = new NamePart(NamePartType.FIRST_NAME, "fn");
+        assertTrue(same.equals(name));
+        assertTrue(name.equals(same));
+        assertTrue(same.equals(same));
+
+        // name part that differs in type
+        NamePart diffType = new NamePart(NamePartType.LAST_NAME, "fn");
+        assertFalse(diffType.equals(name));
+        assertFalse(name.equals(diffType));
+        assertTrue(diffType.equals(diffType));
+
+        assertFalse(name.equals("BLA"));
     }
 
     @Test
     }
 
     @Test
-    public void testMatches() {
-        assertTrue(n.matches("fn ln"));
-        assertTrue(n.matches("fn ln sf"));
-        assertTrue(n.matches("fn mn ln sf"));
-        assertFalse(n.matches("blargh"));
+    public void testNamePartConstructorCheck() {
+        try {
+            new NamePart(null, "a");
+            fail("Exception expected");
+        } catch (IllegalArgumentException e) {
+
+        }
+        try {
+            new NamePart(NamePartType.FIRST_NAME, null);
+            fail("Exception expected");
+        } catch (IllegalArgumentException e) {
+
+        }
+        try {
+            new NamePart(NamePartType.FIRST_NAME, "");
+            fail("Exception expected");
+        } catch (IllegalArgumentException e) {
+
+        }
     }
 
     }
 
+    /**
+     * Testing {@link Name#matches(String)}. For multiple first names.
+     */
+    @Test
+    public void testMatches() throws GigiApiException {
+        Name n0 = new Name(u, new NamePart(NamePartType.FIRST_NAME, "Fir"), new NamePart(NamePartType.FIRST_NAME, "Fir2"), new NamePart(NamePartType.LAST_NAME, "Last"));
+
+        // Having the name "Fir Fir2 Last".
+        // This name requires the Last name to be present and at least one of
+        // the first names.
+
+        // Simple tests...
+        assertTrue(n0.matches("Fir Last"));
+        assertFalse(n0.matches("Fir  Last"));
+        assertFalse(n0.matches("Fir Last "));
+        assertFalse(n0.matches(" Fir Last"));
+
+        // full name
+        assertTrue(n0.matches("Fir Fir2 Last"));
+        // removing and changing parts
+        assertTrue(n0.matches("Fir2 Last"));
+        assertFalse(n0.matches("Fir Bast"));
+        assertFalse(n0.matches("Fir2 Bast"));
+        assertFalse(n0.matches("Fir Fir2 Bast"));
+        // only last-name fails
+        assertFalse(n0.matches("Last"));
+        // one-character first-name is not enough
+        assertFalse(n0.matches("F. Last"));
+        assertFalse(n0.matches("E. Last"));
+        assertFalse(n0.matches("E Last"));
+        assertFalse(n0.matches("F Last"));
+
+        assertFalse(n0.matches("Bast"));
+
+        // test the abbreviated name (for e.g in find-RA-Agent-system)
+        assertEquals("Fir L.", n0.toAbbreviatedString());
+    }
+
+    /**
+     * Testing {@link Name#matches(String)} for multiple last-names and a
+     * suffix.
+     */
+    @Test
+    public void testMatchesLNSuf() throws GigiApiException {
+        Name n0 = new Name(u, new NamePart(NamePartType.FIRST_NAME, "Fir"), new NamePart(NamePartType.LAST_NAME, "Last"), new NamePart(NamePartType.LAST_NAME, "Last2"), new NamePart(NamePartType.SUFFIX, "Suff"));
+
+        // leaving stuff out in order
+        assertTrue(n0.matches("Fir Last"));
+        assertTrue(n0.matches("Fir Last Last2"));
+        assertTrue(n0.matches("Fir Last Last2 Suff"));
+        assertTrue(n0.matches("Fir Last Suff"));
+
+        // omitting primary last name
+        assertFalse(n0.matches("Fir"));
+        assertFalse(n0.matches("Fir Last2"));
+        assertFalse(n0.matches("Fir Last2 Suff"));
+        assertFalse(n0.matches("Fir Suff"));
+
+        // bringing things out of order
+        assertFalse(n0.matches("Fir Last Suff Last2"));
+        assertFalse(n0.matches("Fir Suff Last Last2"));
+        assertFalse(n0.matches("Fir Suff Last"));
+        assertFalse(n0.matches("Fir Last2 Last"));
+        assertFalse(n0.matches("Fir Last2 Last Suff"));
+    }
+
+    /**
+     * Testing {@link Name#matches(String)} for multiple last-names and a
+     * suffix.
+     */
+    @Test
+    public void testMatchesDoubleNameParts() throws GigiApiException {
+        Name name = new Name(u, //
+                new NamePart(NamePartType.FIRST_NAME, "A"), new NamePart(NamePartType.FIRST_NAME, "Fir"), new NamePart(NamePartType.FIRST_NAME, "A"),//
+                new NamePart(NamePartType.LAST_NAME, "A"), new NamePart(NamePartType.LAST_NAME, "Last"), new NamePart(NamePartType.LAST_NAME, "A"));
+
+        assertTrue(name.matches("A A"));
+        assertTrue(name.matches("Fir A"));
+        assertTrue(name.matches("A A Last"));
+        assertTrue(name.matches("A A A"));
+        assertTrue(name.matches("Fir A A A"));
+        assertTrue(name.matches("Fir A A A A"));
+
+        assertFalse(name.matches("A Last"));
+        assertFalse(name.matches("Last A"));
+        assertFalse(name.matches("Last A Last"));
+        assertFalse(name.matches("Fir Last"));
+        assertFalse(name.matches("Fir A A A A A"));
+
+    }
 }
 }
index 69bd4390eb74ff8d5fa52c6bfb0a2fd17ad25e7b..1d35669b8dc68421cf18eb02324250ee9a0e65ff 100644 (file)
@@ -9,10 +9,8 @@ import java.util.Locale;
 
 import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.EmailAddress;
 
 import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.EmailAddress;
-import org.cacert.gigi.dbObjects.Name;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.testUtils.ClientBusinessTest;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.testUtils.ClientBusinessTest;
-import org.cacert.gigi.util.DayDate;
 import org.junit.Test;
 
 public class TestObjectCache extends ClientBusinessTest {
 import org.junit.Test;
 
 public class TestObjectCache extends ClientBusinessTest {
@@ -24,7 +22,7 @@ public class TestObjectCache extends ClientBusinessTest {
         Calendar c = Calendar.getInstance();
         c.set(1950, 1, 1, 0, 0, 0);
         c.set(Calendar.MILLISECOND, 0);
         Calendar c = Calendar.getInstance();
         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);
+        User u = createUser("fname", "lname", createUniqueName() + "@example.org", TEST_PASSWORD);
 
         assertThat(u, is(sameInstance(User.getById(u.getId()))));
         assertThat(User.getById(u.getId()), is(sameInstance(User.getById(u.getId()))));
 
         assertThat(u, is(sameInstance(User.getById(u.getId()))));
         assertThat(User.getById(u.getId()), is(sameInstance(User.getById(u.getId()))));
index 1a26f539f3c286edaf05d592b2c364e01cc63446..65271f6d2db108cb6f9832cbdbe888c4a44cc826 100644 (file)
@@ -4,15 +4,21 @@ import static org.junit.Assert.*;
 
 import java.io.IOException;
 import java.sql.SQLException;
 
 import java.io.IOException;
 import java.sql.SQLException;
+import java.util.Arrays;
 import java.util.Locale;
 
 import org.cacert.gigi.dbObjects.Assurance;
 import java.util.Locale;
 
 import org.cacert.gigi.dbObjects.Assurance;
+import org.cacert.gigi.dbObjects.Assurance.AssuranceType;
 import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.EmailAddress;
 import org.cacert.gigi.dbObjects.Name;
 import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.EmailAddress;
 import org.cacert.gigi.dbObjects.Name;
+import org.cacert.gigi.dbObjects.NamePart;
+import org.cacert.gigi.dbObjects.NamePart.NamePartType;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.testUtils.BusinessTest;
 import org.cacert.gigi.util.DayDate;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.testUtils.BusinessTest;
 import org.cacert.gigi.util.DayDate;
+import org.cacert.gigi.util.Notary;
+import org.hamcrest.CoreMatchers;
 import org.junit.Test;
 
 public class TestUser extends BusinessTest {
 import org.junit.Test;
 
 public class TestUser extends BusinessTest {
@@ -21,10 +27,10 @@ public class TestUser extends BusinessTest {
     public void testStoreAndLoad() throws SQLException, GigiApiException {
         long dob = System.currentTimeMillis();
         dob -= dob % (1000 * 60 * 60 * 24);
     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 DayDate(dob), Locale.ENGLISH);
+        User u = createUser("f", "l", createUniqueName() + "a@email.org", TEST_PASSWORD);
         int id = u.getId();
         User u2 = User.getById(id);
         int id = u.getId();
         User u2 = User.getById(id);
-        assertEquals(u.getName(), u2.getName());
+        assertEquals(u.getNames()[0], u2.getNames()[0]);
         assertEquals(u.getDoB().toString(), u2.getDoB().toString());
         assertEquals(u.getEmail(), u2.getEmail());
     }
         assertEquals(u.getDoB().toString(), u2.getDoB().toString());
         assertEquals(u.getEmail(), u2.getEmail());
     }
@@ -33,11 +39,11 @@ public class TestUser extends BusinessTest {
     public void testWebStoreAndLoad() throws SQLException, GigiApiException {
         int id = createVerifiedUser("aä", "b", createUniqueName() + "a@email.org", TEST_PASSWORD);
 
     public void testWebStoreAndLoad() throws SQLException, GigiApiException {
         int id = createVerifiedUser("aä", "b", createUniqueName() + "a@email.org", TEST_PASSWORD);
 
-        Name u = User.getById(id).getName();
+        Name u = User.getById(id).getNames()[0];
 
 
-        assertEquals("aä", u.getFname());
-        assertEquals("b", u.getLname());
-        assertEquals("", u.getMname());
+        assertThat(Arrays.asList(u.getParts()), CoreMatchers.hasItem(new NamePart(NamePartType.FIRST_NAME, "aä")));
+        assertThat(Arrays.asList(u.getParts()), CoreMatchers.hasItem(new NamePart(NamePartType.LAST_NAME, "b")));
+        assertEquals(2, u.getParts().length);
     }
 
     @Test
     }
 
     @Test
@@ -52,26 +58,17 @@ public class TestUser extends BusinessTest {
         assertEquals(2, expPoints);
         assertTrue(u.hasPassedCATS());
         assertEquals(10, u.getMaxAssurePoints());
         assertEquals(2, expPoints);
         assertTrue(u.hasPassedCATS());
         assertEquals(10, u.getMaxAssurePoints());
-        Name name = u.getName();
-        assertEquals("aä", name.getFname());
-        assertEquals("b", name.getLname());
-        assertEquals("", name.getMname());
     }
 
     @Test
     }
 
     @Test
-    public void testMatcherMethods() throws SQLException, GigiApiException, IOException {
+    public void testMatcherMethodsDomain() throws SQLException, GigiApiException, IOException {
         String uq = createUniqueName();
         int id = createVerifiedUser("aä", "b", uq + "a@email.org", TEST_PASSWORD);
 
         User u = User.getById(id);
         String uq = createUniqueName();
         int id = createVerifiedUser("aä", "b", uq + "a@email.org", TEST_PASSWORD);
 
         User u = User.getById(id);
-        new EmailAddress(u, uq + "b@email.org", Locale.ENGLISH);
-        getMailReceiver().receive().verify();
-        new EmailAddress(u, uq + "c@email.org", Locale.ENGLISH);
-        getMailReceiver().receive();// no-verify
         verify(new Domain(u, u, uq + "a-testdomain.org"));
         verify(new Domain(u, u, uq + "b-testdomain.org"));
         verify(new Domain(u, u, uq + "c-testdomain.org"));
         verify(new Domain(u, u, uq + "a-testdomain.org"));
         verify(new Domain(u, u, uq + "b-testdomain.org"));
         verify(new Domain(u, u, uq + "c-testdomain.org"));
-        assertEquals(3, u.getEmails().length);
         assertEquals(3, u.getDomains().length);
         assertTrue(u.isValidDomain(uq + "a-testdomain.org"));
         assertTrue(u.isValidDomain(uq + "b-testdomain.org"));
         assertEquals(3, u.getDomains().length);
         assertTrue(u.isValidDomain(uq + "a-testdomain.org"));
         assertTrue(u.isValidDomain(uq + "b-testdomain.org"));
@@ -80,12 +77,40 @@ public class TestUser extends BusinessTest {
         assertTrue(u.isValidDomain("*." + uq + "a-testdomain.org"));
         assertFalse(u.isValidDomain("a" + uq + "a-testdomain.org"));
         assertFalse(u.isValidDomain("b" + uq + "a-testdomain.org"));
         assertTrue(u.isValidDomain("*." + uq + "a-testdomain.org"));
         assertFalse(u.isValidDomain("a" + uq + "a-testdomain.org"));
         assertFalse(u.isValidDomain("b" + uq + "a-testdomain.org"));
+    }
+
+    @Test
+    public void testMatcherMethodsEmail() throws SQLException, GigiApiException, IOException {
+        String uq = createUniqueName();
+        int id = createVerifiedUser("aä", "b", uq + "a@email.org", TEST_PASSWORD);
+
+        User u = User.getById(id);
+
+        new EmailAddress(u, uq + "b@email.org", Locale.ENGLISH);
+        getMailReceiver().receive().verify();
+        new EmailAddress(u, uq + "c@email.org", Locale.ENGLISH);
+        getMailReceiver().receive();// no-verify
+        assertEquals(3, u.getEmails().length);
 
         assertTrue(u.isValidEmail(uq + "a@email.org"));
         assertTrue(u.isValidEmail(uq + "b@email.org"));
         assertFalse(u.isValidEmail(uq + "b+6@email.org"));
         assertFalse(u.isValidEmail(uq + "b*@email.org"));
         assertFalse(u.isValidEmail(uq + "c@email.org"));
 
         assertTrue(u.isValidEmail(uq + "a@email.org"));
         assertTrue(u.isValidEmail(uq + "b@email.org"));
         assertFalse(u.isValidEmail(uq + "b+6@email.org"));
         assertFalse(u.isValidEmail(uq + "b*@email.org"));
         assertFalse(u.isValidEmail(uq + "c@email.org"));
+    }
+
+    @Test
+    public void testMatcherMethodsName() throws SQLException, GigiApiException, IOException {
+        String uq = createUniqueName();
+        int id = createVerifiedUser("aä", "b", uq + "a@email.org", TEST_PASSWORD);
+
+        User u = User.getById(id);
+
+        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);
+        }
 
         assertTrue(u.isValidName("aä b"));
         assertFalse(u.isValidName("aä c"));
 
         assertTrue(u.isValidName("aä b"));
         assertFalse(u.isValidName("aä c"));
@@ -97,7 +122,7 @@ public class TestUser extends BusinessTest {
     public void testDoubleInsert() throws GigiApiException {
         long d = System.currentTimeMillis();
         d -= d % DayDate.MILLI_DAY;
     public void testDoubleInsert() throws GigiApiException {
         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);
+        User u = createUser("f", "l", createUniqueName() + "@example.org", TEST_PASSWORD);
         Assurance[] ma = u.getMadeAssurances();
         Assurance[] ma2 = u.getMadeAssurances();
         Assurance[] ra = u.getReceivedAssurances();
         Assurance[] ma = u.getMadeAssurances();
         Assurance[] ma2 = u.getMadeAssurances();
         Assurance[] ra = u.getReceivedAssurances();
index c2825d07dd09ab92809555abfc6a63b09e0a47d3..f6040008fd718b9e0f423c5e45b5a2a90dd7a1ab 100644 (file)
@@ -22,7 +22,6 @@ import org.cacert.gigi.dbObjects.CertificateProfile;
 import org.cacert.gigi.dbObjects.Digest;
 import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.Group;
 import org.cacert.gigi.dbObjects.Digest;
 import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.Group;
-import org.cacert.gigi.dbObjects.Name;
 import org.cacert.gigi.dbObjects.Organisation;
 import org.cacert.gigi.testUtils.ClientTest;
 import org.cacert.gigi.testUtils.IOUtils;
 import org.cacert.gigi.dbObjects.Organisation;
 import org.cacert.gigi.testUtils.ClientTest;
 import org.cacert.gigi.testUtils.IOUtils;
@@ -73,13 +72,12 @@ public class IssueCert extends ClientTest {
     public void testIssueCertAssured() throws Exception {
         makeAssurer(id);
 
     public void testIssueCertAssured() throws Exception {
         makeAssurer(id);
 
-        Name n = u.getName();
-        String whishName = n.getFname() + " " + n.getLname();
-        String cert = issueCert(generatePEMCSR(kp, "EMAIL=" + email + ",CN=" + whishName), "profile=client-a");
+        String intendedName = "a b";
+        String cert = issueCert(generatePEMCSR(kp, "EMAIL=" + email + ",CN=" + intendedName), "profile=client-a");
 
         CertificateFactory cf = CertificateFactory.getInstance("X509");
         java.security.cert.X509Certificate xcert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(cert.getBytes("UTF-8")));
 
         CertificateFactory cf = CertificateFactory.getInstance("X509");
         java.security.cert.X509Certificate xcert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(cert.getBytes("UTF-8")));
-        assertEquals(whishName, ((X500Name) xcert.getSubjectDN()).getCommonName());
+        assertEquals(intendedName, ((X500Name) xcert.getSubjectDN()).getCommonName());
 
     }
 
 
     }
 
index e889f1e838210ac2ea61c54f65f579fda30da4bd..3b8b9927e912107851c71d21765f17e79dad72d0 100644 (file)
@@ -82,6 +82,6 @@ public class TestFindAgent extends RestrictedApiTest {
         grant(email, Group.LOCATE_AGENT);
         grant(User.getById(u2).getEmail(), Group.LOCATE_AGENT);
         res = IOUtils.readURL(doApi(FindAgent.PATH_INFO, "id=" + id + "&id=" + u2)).replace("\r", "");
         grant(email, Group.LOCATE_AGENT);
         grant(User.getById(u2).getEmail(), Group.LOCATE_AGENT);
         res = IOUtils.readURL(doApi(FindAgent.PATH_INFO, "id=" + id + "&id=" + u2)).replace("\r", "");
-        assertEquals(id + ",true," + u.getName().toString() + "\n" + u2 + ",false," + User.getById(u2).getName().toString() + "\n", res);
+        assertEquals(id + ",true," + u.getPreferredName().toAbbreviatedString() + "\n" + u2 + ",false," + User.getById(u2).getPreferredName().toAbbreviatedString() + "\n", res);
     }
 }
     }
 }
index dda8d81de9c3579298d4e49bac4bce256896155f..14c7b35b0361f6d6a5a382697bae188674a20f90 100644 (file)
@@ -37,6 +37,8 @@ public class TestAssurance extends BusinessTest {
 
     private int applicantID;
 
 
     private int applicantID;
 
+    private int applicantNameID;
+
     private User applicant;
 
     private int applicantMultID;
     private User applicant;
 
     private int applicantMultID;
@@ -112,75 +114,67 @@ public class TestAssurance extends BusinessTest {
         agent2ID = createAssuranceUser("a", "d", createUniqueName() + "@example.com", TEST_PASSWORD);
         applicantID = createVerifiedUser("a", "c", createUniqueName() + "@example.com", TEST_PASSWORD);
         applicant = User.getById(applicantID);
         agent2ID = createAssuranceUser("a", "d", createUniqueName() + "@example.com", TEST_PASSWORD);
         applicantID = createVerifiedUser("a", "c", createUniqueName() + "@example.com", TEST_PASSWORD);
         applicant = User.getById(applicantID);
+        applicantNameID = User.getById(applicantID).getPreferredName().getId();
         applicantMultID = createVerifiedUser("a", "e", createUniqueName() + "@example.com", TEST_PASSWORD);
     }
 
     @Test
     public void testVerificationYesterday() throws IOException {
         applicantMultID = createVerifiedUser("a", "e", createUniqueName() + "@example.com", TEST_PASSWORD);
     }
 
     @Test
     public void testVerificationYesterday() throws IOException {
-        enterAssuranceWhen(agentID, applicantID, yesterday);
+        enterAssuranceWhen(agentID, applicantNameID, yesterday);
         assertTrue(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testApprox24MonthAgo() throws IOException {
         assertTrue(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testApprox24MonthAgo() throws IOException {
-        enterAssuranceWhen(agentID, applicantID, min24month);
+        enterAssuranceWhen(agentID, applicantNameID, min24month);
         assertTrue(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testApprox39MonthAgo() throws IOException {
         assertTrue(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testApprox39MonthAgo() throws IOException {
-        enterAssuranceWhen(agentID, applicantID, min39month);
+        enterAssuranceWhen(agentID, applicantNameID, min39month);
         assertFalse(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testTomorrowExpired() throws IOException {
         assertFalse(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testTomorrowExpired() throws IOException {
-        enterAssuranceExpired(agentID, applicantID, tomorrow);
+        enterAssuranceExpired(agentID, applicantNameID, tomorrow);
         assertTrue(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testYesterdayExpired() throws IOException {
         assertTrue(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testYesterdayExpired() throws IOException {
-        enterAssuranceExpired(agentID, applicantID, yesterday);
+        enterAssuranceExpired(agentID, applicantNameID, yesterday);
         assertFalse(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testNormal() throws IOException {
         assertFalse(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testNormal() throws IOException {
-        enterAssurance(agentID, applicantID);
+        enterAssurance(agentID, applicantNameID);
         assertTrue(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testDeletedYesterday() throws IOException {
         assertTrue(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testDeletedYesterday() throws IOException {
-        enterAssuranceDeleted(agentID, applicantID, yesterday);
+        enterAssuranceDeleted(agentID, applicantNameID, yesterday);
         assertFalse(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testMultipleAssurancePossible() throws IOException {
         assertFalse(applicant.isInVerificationLimit());
     }
 
     @Test
     public void testMultipleAssurancePossible() throws IOException {
-
         User agent = User.getById(agentID);
         User applicantMult = User.getById(applicantMultID);
 
         User agent = User.getById(agentID);
         User applicantMult = User.getById(applicantMultID);
 
-        enterAssuranceWhen(agentID, applicantMultID, min39month);
+        enterAssuranceWhen(agentID, applicantMult.getPreferredName().getId(), min39month);
 
         // test that new entry would be possible
 
         // test that new entry would be possible
-        try {
-            Notary.checkAssuranceIsPossible(agent, applicantMult);
-        } catch (GigiApiException e) {
-            assertTrue(false);
-        }
+        assertTrue(Notary.checkAssuranceIsPossible(agent, applicantMult.getPreferredName()));
 
         // enter new entry
 
         // enter new entry
-        enterAssuranceWhen(agentID, applicantMultID, yesterday);
+        enterAssuranceWhen(agentID, applicantMult.getPreferredName().getId(), yesterday);
 
         // test that new entry is not possible
 
         // test that new entry is not possible
-        try {
-            Notary.checkAssuranceIsPossible(agent, applicantMult);
-        } catch (GigiApiException e) {
-            assertTrue(true);
-        }
+        assertFalse(Notary.checkAssuranceIsPossible(agent, applicantMult.getPreferredName()));
 
     }
 
 
     }
 
@@ -190,8 +184,7 @@ public class TestAssurance extends BusinessTest {
         User agent = User.getById(agentID);
         User applicantMult = User.getById(applicantMultID);
 
         User agent = User.getById(agentID);
         User applicantMult = User.getById(applicantMultID);
 
-        enterAssuranceWhen(agentID, applicantMultID, min39month);
-
+        enterAssuranceWhen(agentID, applicantMult.getPreferredName().getId(), min39month);
         int xPoints = agent.getExperiencePoints();
 
         // test that VP after first entry
         int xPoints = agent.getExperiencePoints();
 
         // test that VP after first entry
@@ -199,40 +192,41 @@ public class TestAssurance extends BusinessTest {
         assertEquals(applicantMult.getAssurancePoints(), 10);
 
         // enter second entry to check correct calculation with larger points
         assertEquals(applicantMult.getAssurancePoints(), 10);
 
         // enter second entry to check correct calculation with larger points
-        enterAssuranceWhen(agentID, applicantMultID, min24month, 20);
+        enterAssuranceWhen(agentID, applicantMult.getPreferredName().getId(), min24month, 20);
         assertEquals(applicantMult.getAssurancePoints(), 20);
 
         // test correct XP calculation
         assertEquals(agent.getExperiencePoints(), xPoints);
 
         // enter third entry to check correct calculation with less points
         assertEquals(applicantMult.getAssurancePoints(), 20);
 
         // test correct XP calculation
         assertEquals(agent.getExperiencePoints(), xPoints);
 
         // enter third entry to check correct calculation with less points
-        enterAssuranceWhen(agentID, applicantMultID, yesterday, 15);
+        enterAssuranceWhen(agentID, applicantMult.getPreferredName().getId(), yesterday, 15);
         assertEquals(applicantMult.getAssurancePoints(), 15);
 
         // test correct XP calculation
         assertEquals(agent.getExperiencePoints(), xPoints);
 
         // enter expired entry
         assertEquals(applicantMult.getAssurancePoints(), 15);
 
         // test correct XP calculation
         assertEquals(agent.getExperiencePoints(), xPoints);
 
         // enter expired entry
-        enterAssuranceExpired(agentID, applicantMultID, yesterday);
+        enterAssuranceExpired(agentID, applicantMult.getPreferredName().getId(), yesterday);
         assertEquals(applicantMult.getAssurancePoints(), 15);
 
         // enter deleted entry same agent
         assertEquals(applicantMult.getAssurancePoints(), 15);
 
         // enter deleted entry same agent
-        enterAssuranceDeleted(agentID, applicantMultID, yesterday);
+        enterAssuranceDeleted(agentID, applicantMult.getPreferredName().getId(), yesterday);
         assertEquals(applicantMult.getAssurancePoints(), 15);
 
         // enter expired entry future
         assertEquals(applicantMult.getAssurancePoints(), 15);
 
         // enter expired entry future
-        enterAssuranceExpired(agentID, applicantMultID, tomorrow);
+        enterAssuranceExpired(agentID, applicantMult.getPreferredName().getId(), tomorrow);
         assertEquals(applicantMult.getAssurancePoints(), 10);
 
         // test correct XP calculation
         assertEquals(agent.getExperiencePoints(), xPoints);
 
         // enter entry from different agent
         assertEquals(applicantMult.getAssurancePoints(), 10);
 
         // test correct XP calculation
         assertEquals(agent.getExperiencePoints(), xPoints);
 
         // enter entry from different agent
-        enterAssuranceWhen(agent2ID, applicantMultID, yesterday);
+        enterAssuranceWhen(agent2ID, applicantMult.getPreferredName().getId(), yesterday);
         assertEquals(applicantMult.getAssurancePoints(), 20);
 
         // enter entry for second applicant
         assertEquals(applicantMult.getAssurancePoints(), 20);
 
         // enter entry for second applicant
-        enterAssuranceWhen(agentID, applicantID, yesterday);
+        enterAssuranceWhen(agentID, applicant.getPreferredName().getId(), yesterday);
+
         assertEquals(agent.getExperiencePoints(), xPoints + 2);
 
     }
         assertEquals(agent.getExperiencePoints(), xPoints + 2);
 
     }
diff --git a/tests/org/cacert/gigi/dbObjects/TestAssureName.java b/tests/org/cacert/gigi/dbObjects/TestAssureName.java
new file mode 100644 (file)
index 0000000..9296e35
--- /dev/null
@@ -0,0 +1,32 @@
+package org.cacert.gigi.dbObjects;
+
+import static org.junit.Assert.*;
+
+import org.cacert.gigi.GigiApiException;
+import org.cacert.gigi.dbObjects.Assurance.AssuranceType;
+import org.cacert.gigi.dbObjects.NamePart.NamePartType;
+import org.cacert.gigi.testUtils.ClientBusinessTest;
+import org.cacert.gigi.util.Notary;
+import org.junit.Test;
+
+public class TestAssureName extends ClientBusinessTest {
+
+    @Test
+    public void testIt() throws GigiApiException {
+        User u0 = User.getById(createAssuranceUser("f", "l", createUniqueName() + "@email.com", TEST_PASSWORD));
+        Name n2 = new Name(u, new NamePart(NamePartType.SINGLE_NAME, "Testiaa"));
+        Name n3 = new Name(u, new NamePart(NamePartType.SINGLE_NAME, "Testiaa"));
+        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);
+        assertEquals(10, n0.getAssurancePoints());
+        Notary.assure(u0, u, n2, u.getDoB(), 10, "test mgr", "2010-01-01", 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);
+        assertEquals(10, n3.getAssurancePoints());
+        Notary.assure(u0, u, n4, u.getDoB(), 10, "test mgr", "2010-01-01", AssuranceType.FACE_TO_FACE);
+        assertEquals(10, n4.getAssurancePoints());
+        assertEquals(10, u.getMaxAssurePoints());
+    }
+}
index e6361eb635fd99718d567d4a2d7ad20f24f321ca..6917a1418b2d9d94a1d7adace4f3c5c4ba9fdf8d 100644 (file)
@@ -4,11 +4,17 @@ import static org.junit.Assert.*;
 
 import java.io.IOException;
 import java.sql.Date;
 
 import java.io.IOException;
 import java.sql.Date;
+import java.util.Arrays;
 import java.util.Calendar;
 import java.util.TimeZone;
 
 import java.util.Calendar;
 import java.util.TimeZone;
 
+import org.cacert.gigi.GigiApiException;
+import org.cacert.gigi.dbObjects.Name;
+import org.cacert.gigi.dbObjects.NamePart;
+import org.cacert.gigi.dbObjects.NamePart.NamePartType;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.testUtils.ManagedTest;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.testUtils.ManagedTest;
+import org.hamcrest.CoreMatchers;
 import org.junit.Test;
 
 public class TestMyDetailsEdit extends ManagedTest {
 import org.junit.Test;
 
 public class TestMyDetailsEdit extends ManagedTest {
@@ -22,81 +28,42 @@ public class TestMyDetailsEdit extends ManagedTest {
     public TestMyDetailsEdit() throws IOException {}
 
     @Test
     public TestMyDetailsEdit() throws IOException {}
 
     @Test
-    public void testChangeFnameValid() throws IOException {
+    public void testAddName() throws IOException {
+        int startn = User.getById(id).getNames().length;
         String newName = createUniqueName();
         String newName = createUniqueName();
-        assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "fname=" + newName + "&lname=Hansel&mname=&suffix=&day=1&month=1&year=2000&processDetails", 0));
+        assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "fname=" + newName + "&lname=Hansel&action=addName", 0));
         User u = User.getById(id);
         User u = User.getById(id);
-        assertEquals(newName, u.getName().getFname());
-    }
 
 
-    @Test
-    public void testChangeLnameValid() throws IOException {
-        String newName = createUniqueName();
-        assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "lname=" + newName + "&fname=Kurti&mname=&suffix=&day=1&month=1&year=2000&processDetails", 0));
-        User u = User.getById(id);
-        assertEquals(newName, u.getName().getLname());
-    }
-
-    @Test
-    public void testChangeMnameValid() throws IOException {
-        String newName = createUniqueName();
-        assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "mname=" + newName + "&fname=Kurti&lname=Hansel&suffix=&day=1&month=1&year=2000&processDetails", 0));
-        User u = User.getById(id);
-        assertEquals(newName, u.getName().getMname());
-    }
-
-    @Test
-    public void testChangeSuffixValid() throws IOException {
-        String newName = createUniqueName();
-        assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "mname=&fname=Kurti&lname=Hansel&suffix=" + newName + "&day=1&month=1&year=2000&processDetails", 0));
-        User u = User.getById(id);
-        assertEquals(newName, u.getName().getSuffix());
+        NamePart[] parts = u.getNames()[startn].getParts();
+        assertThat(Arrays.asList(parts), CoreMatchers.hasItem(new NamePart(NamePartType.FIRST_NAME, newName)));
+        assertThat(Arrays.asList(parts), CoreMatchers.hasItem(new NamePart(NamePartType.LAST_NAME, "Hansel")));
+        assertEquals(2, parts.length);
+        assertEquals(startn + 1, User.getById(id).getNames().length);
     }
 
     @Test
     }
 
     @Test
-    public void testUnsetSuffix() throws IOException {
+    public void testDelName() throws IOException, GigiApiException {
+        User user = User.getById(id);
+        int startn = user.getNames().length;
         String newName = createUniqueName();
         String newName = createUniqueName();
-        assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "mname=&fname=Kurti&lname=Hansel&suffix=" + newName + "&day=1&month=1&year=2000&processDetails", 0));
-        clearCaches();
-        User u = User.getById(id);
-        assertEquals(newName, u.getName().getSuffix());
-        assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "mname=&fname=Kurti&lname=Hansel&suffix=&day=1&month=1&year=2000&processDetails", 0));
-        clearCaches();
-        u = User.getById(id);
-        assertEquals("", u.getName().getSuffix());
-    }
-
-    @Test
-    public void testUnsetFname() throws IOException {
-        assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "fname=&lname=Hansel&mname=&suffix=&day=1&month=1&year=2000&processDetails", 0));
-        User u = User.getById(id);
-        assertEquals("", u.getName().getFname());
+        Name n1 = new Name(user, new NamePart(NamePartType.SINGLE_NAME, newName));
 
 
+        assertEquals(startn + 1, user.getNames().length);
+        assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "removeName=" + n1.getId(), 0));
+        assertEquals(startn, user.getNames().length);
     }
 
     @Test
     }
 
     @Test
-    public void testUnsetLname() throws IOException {
-        assertNotNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "lname=&fname=Kurti&mname=&suffix=&day=1&month=1&year=2000&processDetails", 0));
-        User u = User.getById(id);
-        assertEquals("Hansel", u.getName().getLname());
-    }
-
-    @Test
-    public void testUnsetMname() throws IOException {
-        String newName = createUniqueName();
-        assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "mname=" + newName + "&fname=Kurti&lname=Hansel&suffix=&day=1&month=1&year=2000&processDetails", 0));
-        User u = User.getById(id);
-        assertEquals(newName, u.getName().getMname());
-        assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "lname=Hansel&fname=Kurti&mname=&suffix=&day=1&month=1&year=2000&processDetails", 0));
-        clearCaches();
-        u = User.getById(id);
-        assertEquals("", u.getName().getMname());
-
+    public void testDelDefaultName() throws IOException {
+        User user = User.getById(id);
+        assertEquals(1, user.getNames().length);
+        assertNotNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "removeName=" + user.getNames()[0].getId(), 0));
+        assertEquals(1, user.getNames().length);
     }
 
     @Test
     public void testChangeDOBValid() throws IOException {
     }
 
     @Test
     public void testChangeDOBValid() throws IOException {
-        assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "lname=Hansel&fname=Kurti&mname=&suffix=&day=1&month=2&year=2000&processDetails", 0));
+        assertNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "day=1&month=2&year=2000&action=updateDoB", 0));
         User u = User.getById(id);
         Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
         cal.set(Calendar.YEAR, 2000);
         User u = User.getById(id);
         Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
         cal.set(Calendar.YEAR, 2000);
@@ -108,6 +75,6 @@ public class TestMyDetailsEdit extends ManagedTest {
 
     @Test
     public void testChangeDOBInvalid() throws IOException {
 
     @Test
     public void testChangeDOBInvalid() throws IOException {
-        assertNotNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "lname=Hansel&fname=Kurti&mname=&suffix=&day=1&month=1&year=test&processDetails", 0));
+        assertNotNull(executeBasicWebInteraction(cookie, MyDetails.PATH, "day=1&month=1&year=test&action=updateDoB", 0));
     }
 }
     }
 }
index d39bfba2fe26c46f3c9bcbee70dce1daf588e9c2..1ec408a5083c9f3ef8159c9883cebb05df6b06f9 100644 (file)
@@ -28,7 +28,7 @@ public class TestPasswordResetExternal extends ClientTest {
         String cookie2 = login(u.getEmail(), TEST_PASSWORD);
         URLConnection uc = TestAssurance.buildupAssureFormConnection(cookie2, email, true);
         String avalue = RandomToken.generateToken(32);
         String cookie2 = login(u.getEmail(), TEST_PASSWORD);
         URLConnection uc = TestAssurance.buildupAssureFormConnection(cookie2, email, true);
         String avalue = RandomToken.generateToken(32);
-        uc.getOutputStream().write(("date=1910-01-01&location=testcase&certify=1&rules=1&assertion=1&points=10&passwordReset=1&passwordResetValue=" + URLEncoder.encode(avalue, "UTF-8")).getBytes("UTF-8"));
+        uc.getOutputStream().write(("assuredName=" + u.getPreferredName().getId() + "&date=1910-01-01&location=testcase&certify=1&rules=1&assertion=1&points=10&passwordReset=1&passwordResetValue=" + URLEncoder.encode(avalue, "UTF-8")).getBytes("UTF-8"));
         uc.getOutputStream().flush();
         String error = fetchStartErrorMessage(IOUtils.readURL(uc));
         assertNull(error);
         uc.getOutputStream().flush();
         String error = fetchStartErrorMessage(IOUtils.readURL(uc));
         assertNull(error);
index ae89544f155c6a7de5756d429a47f01fc3ffddc9..bd64f9bf2e0da906ef282323ea588b0912eb7ad2 100644 (file)
@@ -31,11 +31,11 @@ public class TestSEAdminNotificationMail extends ClientTest {
     @Test
     public void testChangeAccountData() throws MalformedURLException, IOException {
 
     @Test
     public void testChangeAccountData() throws MalformedURLException, IOException {
 
-        executeBasicWebInteraction(cookie, SupportUserDetailsPage.PATH + targetID, "fname=Kurti3&lname=Hansel&mname=&suffix=&dobd=1&dobm=2&doby=2000&detailupdate", 0);
+        executeBasicWebInteraction(cookie, SupportUserDetailsPage.PATH + targetID, "dobd=1&dobm=2&doby=2000&detailupdate", 0);
 
         String message = getMailReceiver().receive().getMessage();
         assertThat(message, containsString("The account data was changed."));
 
         String message = getMailReceiver().receive().getMessage();
         assertThat(message, containsString("The account data was changed."));
-        assertThat(message, containsString("supporter " + u.getName() + " triggered:"));
+        assertThat(message, containsString("supporter " + u.getPreferredName().toString() + " triggered:"));
 
     }
 
 
     }
 
index edcd43442c2646bd3bf0811d99320bd9e802a0c6..228528b7074cafaa338ef8628603a8f504be739e 100644 (file)
@@ -16,7 +16,6 @@ import org.cacert.gigi.dbObjects.Group;
 import org.cacert.gigi.dbObjects.ObjectCache;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.pages.account.History;
 import org.cacert.gigi.dbObjects.ObjectCache;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.pages.account.History;
-import org.cacert.gigi.pages.account.MyDetails;
 import org.cacert.gigi.pages.admin.support.SupportEnterTicketPage;
 import org.cacert.gigi.pages.admin.support.SupportUserDetailsPage;
 import org.cacert.gigi.testUtils.ClientTest;
 import org.cacert.gigi.pages.admin.support.SupportEnterTicketPage;
 import org.cacert.gigi.pages.admin.support.SupportUserDetailsPage;
 import org.cacert.gigi.testUtils.ClientTest;
@@ -39,8 +38,8 @@ public class TestSEAdminPageDetails extends ClientTest {
         URLConnection uc = get(SupportUserDetailsPage.PATH + id);
         uc.setDoOutput(true);
         String res = IOUtils.readURL(uc);
         URLConnection uc = get(SupportUserDetailsPage.PATH + id);
         uc.setDoOutput(true);
         String res = IOUtils.readURL(uc);
-        assertThat(res, containsString("type=\"text\" value=\"" + fname + "\" name=\"fname\">"));
-        assertThat(res, containsString("type=\"text\" value=\"" + lname + "\" name=\"lname\">"));
+        assertThat(res, containsString(fname));
+        assertThat(res, containsString(lname));
         assertThat(res, containsString(email));
     }
 
         assertThat(res, containsString(email));
     }
 
@@ -69,31 +68,6 @@ public class TestSEAdminPageDetails extends ClientTest {
         assertEquals(2, countRegex(res, Pattern.quote(email2)));
     }
 
         assertEquals(2, countRegex(res, Pattern.quote(email2)));
     }
 
-    @Test
-    public void testUserDetailsEdit() throws MalformedURLException, IOException {
-        String email = createUniqueName() + "@example.com";
-        String fname = "Först";
-        String lname = "Secönd";
-        int id = createVerifiedUser(fname, lname, email, TEST_PASSWORD);
-
-        String userCookie = login(email, TEST_PASSWORD);
-        assertEquals("Först", getFname(IOUtils.readURL(get(userCookie, MyDetails.PATH))));
-        // User can change his name
-        assertNull(executeBasicWebInteraction(userCookie, MyDetails.PATH, "fname=Kurti&lname=Hansel&mname=&suffix=&day=1&month=1&year=2000&processDetails", 0));
-        assertEquals("Kurti", getFname(IOUtils.readURL(get(userCookie, MyDetails.PATH))));
-        // But when assurer
-        makeAssurer(id);
-        // User cannot change his name, and the form changed
-        assertNotNull(executeBasicWebInteraction(userCookie, MyDetails.PATH, "fname=Kurti2&lname=Hansel&mname=&suffix=&day=1&month=1&year=2000&processDetails", 0));
-        assertNull(getFname(IOUtils.readURL(get(userCookie, MyDetails.PATH))));
-        assertEquals("Kurti", getFnamePlain(IOUtils.readURL(get(userCookie, MyDetails.PATH))));
-
-        // but support still can
-        assertNull(executeBasicWebInteraction(cookie, SupportUserDetailsPage.PATH + id, "fname=Kurti3&lname=Hansel&mname=&suffix=&dobd=1&dobm=2&doby=2000&detailupdate", 0));
-        assertEquals("Kurti3", getFnamePlain(IOUtils.readURL(get(userCookie, MyDetails.PATH))));
-
-    }
-
     @Test
     public void testUserDetailsEditToLog() throws MalformedURLException, IOException {
         String email = createUniqueName() + "@example.com";
     @Test
     public void testUserDetailsEditToLog() throws MalformedURLException, IOException {
         String email = createUniqueName() + "@example.com";
@@ -105,29 +79,29 @@ public class TestSEAdminPageDetails extends ClientTest {
         assertEquals(0, logCountAdmin(id));
         assertEquals(0, logCountUser(clientCookie));
         // chaniging both leads to 2 entries
         assertEquals(0, logCountAdmin(id));
         assertEquals(0, logCountUser(clientCookie));
         // chaniging both leads to 2 entries
-        assertNull(executeBasicWebInteraction(cookie, SupportUserDetailsPage.PATH + id, "fname=Kurti&lname=Hansel&mname=&suffix=&dobd=1&dobm=2&doby=2000&detailupdate", 0));
-        assertEquals(2, logCountAdmin(id));
-        assertEquals(2, logCountUser(clientCookie));
+        assertNull(executeBasicWebInteraction(cookie, SupportUserDetailsPage.PATH + id, "dobd=1&dobm=2&doby=2000&detailupdate", 0));
+        assertEquals(1, logCountAdmin(id));
+        assertEquals(1, logCountUser(clientCookie));
 
         // Sending same data keeps same
 
         // Sending same data keeps same
-        assertNull(executeBasicWebInteraction(cookie, SupportUserDetailsPage.PATH + id, "fname=Kurti&lname=Hansel&mname=&suffix=&dobd=1&dobm=2&doby=2000&detailupdate", 0));
+        assertNull(executeBasicWebInteraction(cookie, SupportUserDetailsPage.PATH + id, "dobd=1&dobm=2&doby=2000&detailupdate", 0));
+        assertEquals(1, logCountAdmin(id));
+        assertEquals(1, logCountUser(clientCookie));
+
+        // changing one leads to one entry
+        assertNull(executeBasicWebInteraction(cookie, SupportUserDetailsPage.PATH + id, "dobd=1&dobm=3&doby=2000&detailupdate", 0));
         assertEquals(2, logCountAdmin(id));
         assertEquals(2, logCountUser(clientCookie));
 
         // changing one leads to one entry
         assertEquals(2, logCountAdmin(id));
         assertEquals(2, logCountUser(clientCookie));
 
         // changing one leads to one entry
-        assertNull(executeBasicWebInteraction(cookie, SupportUserDetailsPage.PATH + id, "fname=Kurti2&lname=Hansel&mname=&suffix=&dobd=1&dobm=2&doby=2000&detailupdate", 0));
+        assertNull(executeBasicWebInteraction(cookie, SupportUserDetailsPage.PATH + id, "dobd=2&dobm=3&doby=2000&detailupdate", 0));
         assertEquals(3, logCountAdmin(id));
         assertEquals(3, logCountUser(clientCookie));
 
         assertEquals(3, logCountAdmin(id));
         assertEquals(3, logCountUser(clientCookie));
 
-        // changing one leads to one entry
-        assertNull(executeBasicWebInteraction(cookie, SupportUserDetailsPage.PATH + id, "fname=Kurti2&lname=Hansel&mname=&suffix=&dobd=2&dobm=2&doby=2000&detailupdate", 0));
-        assertEquals(4, logCountAdmin(id));
-        assertEquals(4, logCountUser(clientCookie));
-
         // changing none -> no entry
         // changing none -> no entry
-        assertNull(executeBasicWebInteraction(cookie, SupportUserDetailsPage.PATH + id, "fname=Kurti2&lname=Hansel&mname=&suffix=&dobd=2&dobm=2&doby=2000&detailupdate", 0));
-        assertEquals(4, logCountAdmin(id));
-        assertEquals(4, logCountUser(clientCookie));
+        assertNull(executeBasicWebInteraction(cookie, SupportUserDetailsPage.PATH + id, "dobd=2&dobm=3&doby=2000&detailupdate", 0));
+        assertEquals(3, logCountAdmin(id));
+        assertEquals(3, logCountUser(clientCookie));
 
     }
 
 
     }
 
@@ -154,7 +128,7 @@ public class TestSEAdminPageDetails extends ClientTest {
     }
 
     private String getFname(String res) {
     }
 
     private String getFname(String res) {
-        Pattern p = Pattern.compile("type=\"text\" name=\"fname\" value=\"([^\"]*)\">");
+        Pattern p = Pattern.compile("<span class='fname'>([^<]*)</span>");
         Matcher m = p.matcher(res);
         if (m.find()) {
             return m.group(1);
         Matcher m = p.matcher(res);
         if (m.find()) {
             return m.group(1);
@@ -162,12 +136,4 @@ public class TestSEAdminPageDetails extends ClientTest {
         return null;
     }
 
         return null;
     }
 
-    private String getFnamePlain(String res) {
-        Pattern p = Pattern.compile("\\s*<td[^>]*>First Name: </td>\\s*<td[^>]*>([^<]*)</td>");
-        Matcher m = p.matcher(res);
-        if (m.find()) {
-            return m.group(1);
-        }
-        return null;
-    }
 }
 }
index 4108cf8f12d04d5a0058919fdf24f7cca63578d0..2a68173d2d7356747084533ba4fda712271f4041 100644 (file)
@@ -32,6 +32,8 @@ public class TestAssurance extends ManagedTest {
 
     private String assureeM;
 
 
     private String assureeM;
 
+    private int assureeName;
+
     private String cookie;
 
     @Before
     private String cookie;
 
     @Before
@@ -41,7 +43,8 @@ public class TestAssurance extends ManagedTest {
         assureeM = createUniqueName() + "@cacert-test.org";
 
         createAssuranceUser("a", "b", assurerM, TEST_PASSWORD);
         assureeM = createUniqueName() + "@cacert-test.org";
 
         createAssuranceUser("a", "b", assurerM, TEST_PASSWORD);
-        createVerifiedUser("a", "c", assureeM, TEST_PASSWORD);
+        int assureeId = createVerifiedUser("a", "c", assureeM, TEST_PASSWORD);
+        assureeName = User.getById(assureeId).getPreferredName().getId();
 
         cookie = login(assurerM, TEST_PASSWORD);
     }
 
         cookie = login(assurerM, TEST_PASSWORD);
     }
@@ -95,7 +98,7 @@ public class TestAssurance extends ManagedTest {
     @Test
     public void testAssureFormContanisData() throws IOException {
         URLConnection uc = buildupAssureFormConnection(true);
     @Test
     public void testAssureFormContanisData() throws IOException {
         URLConnection uc = buildupAssureFormConnection(true);
-        uc.getOutputStream().write(("date=2000-01-01&location=testcase&rules=1&assertion=1&points=10").getBytes("UTF-8"));
+        uc.getOutputStream().write(("assuredName=" + assureeName + "&date=2000-01-01&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"));
         uc.getOutputStream().flush();
         String data = IOUtils.readURL(uc);
         assertThat(data, containsString("2000-01-01"));
@@ -120,36 +123,25 @@ public class TestAssurance extends ManagedTest {
         assertEquals(500, uc.getResponseCode());
     }
 
         assertEquals(500, uc.getResponseCode());
     }
 
-    @Test
-    public void testAssureFormRaceName() throws IOException, SQLException {
-        testAssureFormRace(true, false);
-    }
-
     @Test
     public void testAssureFormRaceDoB() throws IOException, SQLException {
     @Test
     public void testAssureFormRaceDoB() throws IOException, SQLException {
-        testAssureFormRace(false, false);
-    }
-
-    @Test
-    public void testAssureFormRaceNameBlind() throws IOException, SQLException {
-        testAssureFormRace(true, true);
+        testAssureFormRace(false);
     }
 
     @Test
     public void testAssureFormRaceDoBBlind() throws IOException, SQLException {
     }
 
     @Test
     public void testAssureFormRaceDoBBlind() throws IOException, SQLException {
-        testAssureFormRace(false, true);
+        testAssureFormRace(true);
     }
 
     }
 
-    public void testAssureFormRace(boolean name, boolean succeed) throws IOException, SQLException {
+    public void testAssureFormRace(boolean succeed) throws IOException, SQLException {
         URLConnection uc = buildupAssureFormConnection(true);
 
         String assureeCookie = login(assureeM, TEST_PASSWORD);
         URLConnection uc = buildupAssureFormConnection(true);
 
         String assureeCookie = login(assureeM, TEST_PASSWORD);
-        String newName = "lname=" + (name && !succeed ? "a" : "c") + "&fname=a&mname=&suffix=";
-        String newDob = "day=1&month=1&year=" + ( !name && !succeed ? 1911 : 1910);
+        String newDob = "day=1&month=1&year=" + ( !succeed ? 1911 : 1910);
 
 
-        assertNull(executeBasicWebInteraction(assureeCookie, MyDetails.PATH, newName + "&" + newDob + "&processDetails", 0));
+        assertNull(executeBasicWebInteraction(assureeCookie, MyDetails.PATH, newDob + "&action=updateDoB", 0));
 
 
-        uc.getOutputStream().write(("date=2000-01-01&location=testcase&certify=1&rules=1&assertion=1&points=10").getBytes("UTF-8"));
+        uc.getOutputStream().write(("assuredName=" + assureeName + "&date=2000-01-01&location=testcase&certify=1&rules=1&assertion=1&points=10").getBytes("UTF-8"));
         uc.getOutputStream().flush();
         String error = fetchStartErrorMessage(IOUtils.readURL(uc));
         if (succeed) {
         uc.getOutputStream().flush();
         String error = fetchStartErrorMessage(IOUtils.readURL(uc));
         if (succeed) {
@@ -231,7 +223,7 @@ public class TestAssurance extends ManagedTest {
 
     private String execute(String query) throws MalformedURLException, IOException {
         URLConnection uc = buildupAssureFormConnection(true);
 
     private String execute(String query) throws MalformedURLException, IOException {
         URLConnection uc = buildupAssureFormConnection(true);
-        uc.getOutputStream().write((query).getBytes("UTF-8"));
+        uc.getOutputStream().write(("assuredName=" + assureeName + "&" + query).getBytes("UTF-8"));
         uc.getOutputStream().flush();
         return IOUtils.readURL(uc);
     }
         uc.getOutputStream().flush();
         return IOUtils.readURL(uc);
     }
index c014e2b3a22c427ab811ec9c9304eb360da5993a..8de7a5868df942ca775e7496390d5647f32798aa 100644 (file)
@@ -17,7 +17,8 @@ import java.util.regex.Pattern;
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.EmailAddress;
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.EmailAddress;
-import org.cacert.gigi.dbObjects.Name;
+import org.cacert.gigi.dbObjects.NamePart;
+import org.cacert.gigi.dbObjects.NamePart.NamePartType;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.email.EmailProvider;
 import org.cacert.gigi.ping.PingerDaemon;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.email.EmailProvider;
 import org.cacert.gigi.ping.PingerDaemon;
@@ -118,17 +119,14 @@ 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 Name("a", "m", "c", ""), new DayDate(c.getTimeInMillis()), Locale.ENGLISH);
+        User u = new User(createUniqueName() + "@email.com", TEST_PASSWORD, new DayDate(c.getTimeInMillis()), Locale.ENGLISH, //
+                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;
     }
 
     public static int createVerifiedUser(String f, String l, String mail, String pw) throws GigiApiException {
         InVMEmail.getInstance().mails.poll().verify();
         return u;
     }
 
     public static int createVerifiedUser(String f, String l, String mail, String pw) throws GigiApiException {
-        Calendar c = Calendar.getInstance();
-        c.set(1950, 1, 1, 0, 0, 0);
-        c.set(Calendar.MILLISECOND, 0);
-
-        User u = new User(mail, pw, new Name(f, l, "", ""), new DayDate(c.getTimeInMillis()), Locale.ENGLISH);
+        User u = createUser(f, l, mail, pw);
         try {
             InVMEmail.getInstance().mails.poll().verify();
         } catch (IOException e) {
         try {
             InVMEmail.getInstance().mails.poll().verify();
         } catch (IOException e) {
@@ -137,6 +135,16 @@ public abstract class BusinessTest extends ConfiguredTest {
         return u.getId();
     }
 
         return u.getId();
     }
 
+    public static User createUser(String f, String l, String mail, String pw) throws GigiApiException {
+        Calendar c = Calendar.getInstance();
+        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,//
+                new NamePart(NamePartType.FIRST_NAME, f), new NamePart(NamePartType.LAST_NAME, l));
+        return u;
+    }
+
     public static int createAssuranceUser(String f, String l, String mail, String pw) throws GigiApiException {
         int u = createVerifiedUser(f, l, mail, pw);
         makeAssurer(u);
     public static int createAssuranceUser(String f, String l, String mail, String pw) throws GigiApiException {
         int u = createVerifiedUser(f, l, mail, pw);
         makeAssurer(u);
index e096be4c13e4599145095b27e536d82d6ede38b7..31c28686694aefbb722d3cbc787ad6dc29988287 100644 (file)
@@ -1,18 +1,22 @@
 package org.cacert.gigi.testUtils;
 
 import org.cacert.gigi.GigiApiException;
 package org.cacert.gigi.testUtils;
 
 import org.cacert.gigi.GigiApiException;
+import org.cacert.gigi.dbObjects.Name;
 import org.cacert.gigi.dbObjects.User;
 
 public class ClientBusinessTest extends BusinessTest {
 
     protected final User u;
 
 import org.cacert.gigi.dbObjects.User;
 
 public class ClientBusinessTest extends BusinessTest {
 
     protected final User u;
 
+    protected final Name n0;
+
     protected final int id;
 
     public ClientBusinessTest() {
         try {
             id = createVerifiedUser("a", "b", createUniqueName() + "@example.com", TEST_PASSWORD);
             u = User.getById(id);
     protected final int id;
 
     public ClientBusinessTest() {
         try {
             id = createVerifiedUser("a", "b", createUniqueName() + "@example.com", TEST_PASSWORD);
             u = User.getById(id);
+            n0 = u.getNames()[0];
         } catch (GigiApiException e) {
             throw new Error(e);
         }
         } catch (GigiApiException e) {
             throw new Error(e);
         }
index e696acd3a7a2f3ff62e2741a798e52171d10e265..5ab200793be1ada9b60254d7a7cd6007e85a676b 100644 (file)
@@ -26,6 +26,7 @@ import org.cacert.gigi.database.SQLFileManager.ImportType;
 import org.cacert.gigi.dbObjects.CATS.CATSType;
 import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.DomainPingType;
 import org.cacert.gigi.dbObjects.CATS.CATSType;
 import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.DomainPingType;
+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.testUtils.TestEmailReceiver.TestMail;
 import org.cacert.gigi.util.DatabaseManager;
 import org.cacert.gigi.util.DomainAssessment;
@@ -178,7 +179,7 @@ public abstract class ConfiguredTest {
 
         try (GigiPreparedStatement ps2 = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, points='100'")) {
             ps2.setInt(1, uid);
 
         try (GigiPreparedStatement ps2 = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, points='100'")) {
             ps2.setInt(1, uid);
-            ps2.setInt(2, uid);
+            ps2.setInt(2, User.getById(uid).getPreferredName().getId());
             ps2.execute();
         }
     }
             ps2.execute();
         }
     }
index 477345f36e46bd3404732b76d635728752d8a864..21045c9a229b1ef1d87bc453dfb35c5f7d4856a7 100644 (file)
@@ -31,7 +31,7 @@ public class TestNotary extends BusinessTest {
         };
 
         try {
         };
 
         try {
-            Notary.assure(assurer, users[0], users[0].getName(), 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", "2014-01-01", AssuranceType.FACE_TO_FACE);
             fail("This shouldn't have passed");
         } catch (GigiApiException e) {
             // expected
             fail("This shouldn't have passed");
         } catch (GigiApiException e) {
             // expected
@@ -40,7 +40,7 @@ public class TestNotary extends BusinessTest {
             assertEquals(result[i], assurer.getMaxAssurePoints());
 
             assuranceFail(assurer, users[i], result[i] + 1, "test-notary", "2014-01-01");
             assertEquals(result[i], assurer.getMaxAssurePoints());
 
             assuranceFail(assurer, users[i], result[i] + 1, "test-notary", "2014-01-01");
-            Notary.assure(assurer, users[i], users[i].getName(), users[i].getDoB(), result[i], "test-notary", "2014-01-01", AssuranceType.FACE_TO_FACE);
+            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], "test-notary", "2014-01-01");
         }
 
@@ -52,7 +52,7 @@ public class TestNotary extends BusinessTest {
 
     private void assuranceFail(User assurer, User user, int i, String location, String date) throws SQLException {
         try {
 
     private void assuranceFail(User assurer, User user, int i, String location, String date) throws SQLException {
         try {
-            Notary.assure(assurer, user, user.getName(), user.getDoB(), i, location, date, AssuranceType.FACE_TO_FACE);
+            Notary.assure(assurer, user, user.getPreferredName(), user.getDoB(), i, location, date, AssuranceType.FACE_TO_FACE);
             fail("This shouldn't have passed");
         } catch (GigiApiException e) {
             // expected
             fail("This shouldn't have passed");
         } catch (GigiApiException e) {
             // expected
@@ -77,7 +77,7 @@ public class TestNotary extends BusinessTest {
             assuranceFail(assurer, users[i], -1, "test-notary", "2014-01-01");
             assuranceFail(assurer, users[i], 11, "test-notary", "2014-01-01");
             if (User.POJAM_ENABLED) {
             assuranceFail(assurer, users[i], -1, "test-notary", "2014-01-01");
             assuranceFail(assurer, users[i], 11, "test-notary", "2014-01-01");
             if (User.POJAM_ENABLED) {
-                Notary.assure(assurer, users[i], users[i].getName(), 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", "2014-01-01", AssuranceType.FACE_TO_FACE);
             }
             assuranceFail(assurer, users[i], 10, "test-notary", "2014-01-01");
         }
             }
             assuranceFail(assurer, users[i], 10, "test-notary", "2014-01-01");
         }
@@ -113,7 +113,7 @@ public class TestNotary extends BusinessTest {
         assuranceFail(assuree, assuranceUser, 10, "notary-junit-test", "2014-01-01");
 
         // valid
         assuranceFail(assuree, assuranceUser, 10, "notary-junit-test", "2014-01-01");
 
         // valid
-        Notary.assure(assuranceUser, assuree, assuree.getName(), 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", "2014-01-01", AssuranceType.FACE_TO_FACE);
 
         // assure double
         assuranceFail(assuranceUser, assuree, 10, "notary-junit-test", "2014-01-01");
 
         // assure double
         assuranceFail(assuranceUser, assuree, 10, "notary-junit-test", "2014-01-01");
index 254df05a70d5d612e6b755faf15aa26c2e7dea61..94c605915948b57651fdcb34502087432207dbfc 100644 (file)
@@ -2,19 +2,19 @@ package org.cacert.gigi.util;
 
 import static org.junit.Assert.*;
 
 
 import static org.junit.Assert.*;
 
-import org.cacert.gigi.dbObjects.Name;
+import org.cacert.gigi.testUtils.ClientBusinessTest;
 import org.junit.Test;
 
 import org.junit.Test;
 
-public class TestPasswordStrengthChecker {
-
-    Name n = new Name("fname", "lname", "mname", "suffix");
+public class TestPasswordStrengthChecker extends ClientBusinessTest {
 
     String e = "email";
 
     public TestPasswordStrengthChecker() {}
 
     private int check(String pw) {
 
     String e = "email";
 
     public TestPasswordStrengthChecker() {}
 
     private int check(String pw) {
-        return PasswordStrengthChecker.checkpw(pw, n, e);
+        return PasswordStrengthChecker.checkpw(pw, new String[] {
+                "fname", "lname", "mname", "suffix"
+        }, e);
     }
 
     @Test
     }
 
     @Test
index 6a4a521a7b730289ea1b4a8b338c63316b354914..6889bfbe908ba43aef89a43df2c831c1dac26374 100644 (file)
@@ -39,7 +39,8 @@ import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.DomainPingType;
 import org.cacert.gigi.dbObjects.EmailAddress;
 import org.cacert.gigi.dbObjects.Group;
 import org.cacert.gigi.dbObjects.DomainPingType;
 import org.cacert.gigi.dbObjects.EmailAddress;
 import org.cacert.gigi.dbObjects.Group;
-import org.cacert.gigi.dbObjects.Name;
+import org.cacert.gigi.dbObjects.NamePart;
+import org.cacert.gigi.dbObjects.NamePart.NamePartType;
 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;
@@ -203,7 +204,9 @@ 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 Name("Först", "Läst", "Müddle", "Süffix"), new DayDate(gc.getTime().getTime()), Locale.ENGLISH);
+        User u = new User(email, "xvXV12°§", new DayDate(gc.getTime().getTime()), Locale.ENGLISH, //
+                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];
         verify(email, ea);
     }
         EmailAddress ea = u.getEmails()[0];
         verify(email, ea);
     }
@@ -269,7 +272,7 @@ public class Manager extends Page {
             }
             try {
                 for (int i = 0; i < 10; i++) {
             }
             try {
                 for (int i = 0; i < 10; i++) {
-                    Notary.assure(getAssurer(i), byEmail, byEmail.getName(), byEmail.getDoB(), 10, "Testmanager Assure up code", "2014-11-06", AssuranceType.FACE_TO_FACE);
+                    Notary.assure(getAssurer(i), byEmail, byEmail.getPreferredName(), byEmail.getDoB(), 10, "Testmanager Assure up code", "2014-11-06", AssuranceType.FACE_TO_FACE);
                 }
             } catch (GigiApiException e) {
                 throw new Error(e);
                 }
             } catch (GigiApiException e) {
                 throw new Error(e);
@@ -281,7 +284,7 @@ public class Manager extends Page {
             try {
                 for (int i = 0; i < 25; i++) {
                     User a = getAssurer(i);
             try {
                 for (int i = 0; i < 25; i++) {
                     User a = getAssurer(i);
-                    Notary.assure(byEmail, a, a.getName(), a.getDoB(), 10, "Testmanager exp up code", "2014-11-06", AssuranceType.FACE_TO_FACE);
+                    Notary.assure(byEmail, a, a.getNames()[0], a.getDoB(), 10, "Testmanager exp up code", "2014-11-06", AssuranceType.FACE_TO_FACE);
                 }
             } catch (GigiApiException e) {
                 throw new Error(e);
                 }
             } catch (GigiApiException e) {
                 throw new Error(e);