]> 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
-                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");
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;
 
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 '',
-  "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 '',
@@ -377,7 +374,7 @@ CREATE TABLE "schemeVersion" (
   "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` (
@@ -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);
 
+
+
+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 to;
+    private Name to;
 
     private String location;
 
@@ -33,7 +33,7 @@ public class Assurance {
 
     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;
@@ -60,7 +60,7 @@ public class Assurance {
         return points;
     }
 
-    public User getTo() {
+    public Name getTo() {
         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 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;
 
-@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;
         }
-        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;
         }
-        Name other = (Name) obj;
-        if (fname == null) {
-            if (other.fname != null) {
+
+        private boolean tryMatchFirst(String[] tokens, int lastName) {
+            if (lastName == 0) {
                 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) {
-        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;
     }
 
-    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");
-        target.setDoB(dob);
+        target.setDoBAsSupport(dob);
         return true;
     }
 
@@ -88,10 +79,6 @@ public class SupportedUser {
         return target;
     }
 
-    public void submitSupportAction() throws GigiApiException {
-        target.rawUpdateUserData();
-    }
-
     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");
-            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");
index d3d5da02e3a1dc7c65a01b0c9531f9e98b0fb223..91ab46cbe8b3c70aa081208ad0b75c4abe683199 100644 (file)
@@ -28,8 +28,6 @@ import org.cacert.gigi.util.PasswordStrengthChecker;
  */
 public class User extends CertificateOwner {
 
-    private Name name = new Name(null, null, null, null);
-
     private DayDate dob;
 
     private String email;
@@ -55,15 +53,17 @@ public class User extends CertificateOwner {
      */
     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) {
-        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");
+        preferredName = Name.getById(rs.getInt("preferredName"));
 
         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.name = name;
         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(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);
     }
 
-    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 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() {
@@ -135,7 +167,7 @@ public class User extends CertificateOwner {
     }
 
     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());
@@ -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
@@ -180,7 +208,7 @@ public class User extends CertificateOwner {
     }
 
     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();
@@ -195,7 +223,7 @@ public class User extends CertificateOwner {
     }
 
     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());
 
@@ -244,7 +272,12 @@ public class User extends CertificateOwner {
     }
 
     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 {
@@ -287,7 +320,7 @@ public class User extends CertificateOwner {
 
     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();
@@ -332,23 +365,10 @@ public class User extends CertificateOwner {
         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();
         }
     }
@@ -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);
     }
@@ -539,11 +576,11 @@ public class User extends CertificateOwner {
     }
 
     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() {
-        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);
 
@@ -551,4 +588,5 @@ public class User extends CertificateOwner {
             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("myName", "yes");
         }
 
         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("verbVal", assurance.getTo().getName());
+                        vars.put("verbVal", assurance.getTo().getOwner().getPreferredName());
+                        vars.put("myName", assurance.getTo());
                     } 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());
index 4a91eefa19a725af73a518bddf6875a0077ad5fa..ab8516322f55329dca22660ab8e3544e971e979b 100644 (file)
@@ -6,6 +6,7 @@
 <td><?=_Id?></td>
 <td><?=_Date?></td>
 <td><?=$verb?></td>
+<td><?=_Verified Name?></td>
 <td><?=_Points?></td>
 <td><?=_Location?></td>
 <td><?=_Method?></td>
@@ -15,6 +16,9 @@
 <td><?=$id?></td>
 <td><?=$date?></td>
 <td><?=$verbVal?></td>
+<? if($myName) { ?>
+<td><?=$myName?></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 {
-        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);
     }
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.output.ArrayIterable;
 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.util.HTMLEncoder;
 
 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 names = new Template(MyDetailsForm.class.getResource("NamesForm.templ"));
+
     private User target;
 
     private DateSelector ds;
 
+    private NameInput ni;
+
     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 {
-            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));
@@ -64,12 +94,31 @@ public class MyDetailsForm extends Form {
 
     @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);
index d4d3c7e0cee9f7f0f452fe606a02c6853dcf2f25..f9ea0c7244dea6318741f4bb331356878dea68ee 100644 (file)
@@ -1,42 +1,13 @@
 <table class="table">
-<thead>
-  <tr>
-    <th colspan="2"><?=_My Details?></th>
-  </tr>
-  </thead>
   <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>
+    <td><button class="btn btn-primary" name="action" value="updateDoB"><?=_Update Date of Birth?></button></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?>
-  <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>
index 8cfb7705bd017edc39ce3bc75d1b7f08f383dfa1..8dde8c3c6f34aee549d953d2956e5e50e5a6743b 100644 (file)
@@ -1,29 +1,5 @@
 <table class="table">
-<thead>
-  <tr>
-    <th colspan="2"><?=_My Details?></th>
-  </tr>
-  </thead>
   <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>
@@ -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"><?=_View secret question & answers and OTP phrases?></td>
-  </tr>
-  <?=$details?>
   </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) {
-                        name = u.getName().toString();
+                        name = u.getPreferredName().toString();
                     }
                 }
             } else if (name == null || name.equals("")) {
@@ -508,7 +508,7 @@ public class CertificateRequest {
                     if (defaultIsOK) {
                         name = DEFAULT_CN;
                     } else if (realIsOK) {
-                        name = u.getName().toString();
+                        name = u.getPreferredName().toString();
                     }
                 }
             } 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) {
-        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()));
index a6bd0d47308a1d0972b52357e5e7a9dbc9e070f4..2ffd12e2085882175260683572bb7c815230452d 100644 (file)
@@ -74,7 +74,7 @@ public class TTPAdminPage extends Page {
                     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++;
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.output.ArrayIterable;
 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);
-        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!");
         }
-        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);
@@ -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();
-        Name name = user.getName();
         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());
index c4f52d0ece886d911a3922bb31a403aab343fe91..06dbd0423ae9410f8b79f2421364e9bf1758efc4 100644 (file)
@@ -6,26 +6,12 @@
             <td><?=_Email?>:</td>
             <td><?=$mail?></td>
         </tr>
+  <? foreach($exNames) { ?>
         <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>
             <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.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.output.NameInput;
 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 {
 
-    Name buildupName = new Name("", "", "", "");
+    private NameInput ni;
 
-    String email = "";
+    private String email = "";
 
     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);
-
+        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>();
-        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\"" : "");
@@ -62,27 +59,11 @@ public class Signup extends Form {
         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");
         }
-        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"));
@@ -101,9 +82,12 @@ public class Signup extends Form {
 
         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"));
         }
@@ -125,7 +109,7 @@ public class Signup extends Form {
         } 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."));
         }
@@ -177,7 +161,7 @@ public class Signup extends Form {
     }
 
     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());
index 59e22cd4ceffa9ded2c00de750ad2733256e2fa1..c47bf8f1a7d8921eb8651f8adad8c38e423a5b73 100644 (file)
@@ -6,29 +6,10 @@
   </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>
-
-  <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>
index f6a2da7d1af0392ca27ea94c3aa3d6eabb6e8029..6ffc8822d142ace91992f4b171ede427bb72e338 100644 (file)
@@ -63,7 +63,7 @@ public class AffiliationForm extends Form {
                     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;
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.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 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.output.ArrayIterable;
 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;
@@ -26,7 +30,9 @@ public class AssuranceForm extends Form {
 
     private User assuree;
 
-    private Name assureeName;
+    private Name[] assureeNames;
+
+    private boolean[] selected;
 
     private DayDate dob;
 
@@ -42,12 +48,31 @@ public class AssuranceForm extends Form {
 
     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;
-        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();
+        selected = new boolean[assureeNames.length];
     }
 
     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);
-        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()));
@@ -133,11 +167,19 @@ public class AssuranceForm extends Form {
                 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;
         }
-        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:");
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>
-
+<? foreach($names) { ?>
        <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>
                <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.pages.LoginPage;
 import org.cacert.gigi.pages.Page;
 import org.cacert.gigi.util.AuthorizationContext;
-import org.cacert.gigi.util.Notary;
 
 public class AssurePage extends Page {
 
@@ -58,12 +56,7 @@ public class AssurePage extends Page {
                 }
             } 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;
@@ -88,9 +81,7 @@ public class AssurePage extends Page {
 
                     } else {
                         User assuree = User.getById(id);
-                        User myself = LoginPage.getUser(req);
                         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));
index a0c654808bba8909f4a55c4dbf8fe2a97081939c..7fdd5c8fd5adb95b9a64c2bb763921593ceb5dfb 100644 (file)
@@ -1,3 +1,4 @@
+<h2><?=_Verification Points You Received?></h2>
 <?=$pointlist?>
 <h2><?=_Verification Points You Issued?></h2>
 <?=$madelist?>
@@ -6,5 +7,4 @@
 <? 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());
-                    vars.put("target", actor.getName().toString());
+                    vars.put("target", actor.getPreferredName().toString());
                     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();
-            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) {
+            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."));
             }
+
             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) {
-                assureF2F(assurer, assuree, awarded, location, date);
+                assureF2F(assurer, assuree, assureeName, awarded, location, date);
             } else if (type == AssuranceType.NUCLEUS) {
-                assureNucleus(assurer, assuree, awarded, location, date);
+                assureNucleus(assurer, assuree, assureeName, awarded, location, date);
             } 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()));
             }
@@ -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());
-            ps.setInt(2, assuree.getId());
+            ps.setInt(2, name.getId());
             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());
-            ps.setInt(2, assuree.getId());
+            ps.setInt(2, name.getId());
             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.");
     }
 
-    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);
-        assureF2F(assurer, assuree, f2fPoints, location, date);
+        assureF2F(assurer, assuree, name, f2fPoints, location, date);
 
         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());
-            ps.setInt(2, assuree.getId());
+            ps.setInt(2, name.getId());
             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;
 
+import java.util.TreeSet;
 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 {
 
@@ -51,7 +53,7 @@ public class PasswordStrengthChecker {
         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;
         }
@@ -59,24 +61,23 @@ public class PasswordStrengthChecker {
         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;
     }
 
-    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.");
         }
     }
@@ -93,4 +94,5 @@ public class PasswordStrengthChecker {
         }
         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 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;
 
-public class TestName {
-
-    Name n = new Name("fn", "ln", "mn", "sf");
+public class TestName extends ClientBusinessTest {
 
     @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
-    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
-    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.Name;
 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 {
@@ -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);
-        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()))));
index 1a26f539f3c286edaf05d592b2c364e01cc63446..65271f6d2db108cb6f9832cbdbe888c4a44cc826 100644 (file)
@@ -4,15 +4,21 @@ import static org.junit.Assert.*;
 
 import java.io.IOException;
 import java.sql.SQLException;
+import java.util.Arrays;
 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.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.util.Notary;
+import org.hamcrest.CoreMatchers;
 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);
-        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);
-        assertEquals(u.getName(), u2.getName());
+        assertEquals(u.getNames()[0], u2.getNames()[0]);
         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);
 
-        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
@@ -52,26 +58,17 @@ public class TestUser extends BusinessTest {
         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
-    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);
-        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"));
-        assertEquals(3, u.getEmails().length);
         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"));
+    }
+
+    @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"));
+    }
+
+    @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"));
@@ -97,7 +122,7 @@ public class TestUser extends BusinessTest {
     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();
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.Name;
 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);
 
-        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")));
-        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", "");
-        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 applicantNameID;
+
     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);
+        applicantNameID = User.getById(applicantID).getPreferredName().getId();
         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 {
-        enterAssuranceWhen(agentID, applicantID, min24month);
+        enterAssuranceWhen(agentID, applicantNameID, min24month);
         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 {
-        enterAssuranceExpired(agentID, applicantID, tomorrow);
+        enterAssuranceExpired(agentID, applicantNameID, tomorrow);
         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 {
-        enterAssurance(agentID, applicantID);
+        enterAssurance(agentID, applicantNameID);
         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 {
-
         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
-        try {
-            Notary.checkAssuranceIsPossible(agent, applicantMult);
-        } catch (GigiApiException e) {
-            assertTrue(false);
-        }
+        assertTrue(Notary.checkAssuranceIsPossible(agent, applicantMult.getPreferredName()));
 
         // enter new entry
-        enterAssuranceWhen(agentID, applicantMultID, yesterday);
+        enterAssuranceWhen(agentID, applicantMult.getPreferredName().getId(), yesterday);
 
         // 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);
 
-        enterAssuranceWhen(agentID, applicantMultID, min39month);
-
+        enterAssuranceWhen(agentID, applicantMult.getPreferredName().getId(), min39month);
         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
-        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
-        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
-        enterAssuranceExpired(agentID, applicantMultID, yesterday);
+        enterAssuranceExpired(agentID, applicantMult.getPreferredName().getId(), yesterday);
         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
-        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
-        enterAssuranceWhen(agent2ID, applicantMultID, yesterday);
+        enterAssuranceWhen(agent2ID, applicantMult.getPreferredName().getId(), yesterday);
         assertEquals(applicantMult.getAssurancePoints(), 20);
 
         // enter entry for second applicant
-        enterAssuranceWhen(agentID, applicantID, yesterday);
+        enterAssuranceWhen(agentID, applicant.getPreferredName().getId(), yesterday);
+
         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.util.Arrays;
 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.hamcrest.CoreMatchers;
 import org.junit.Test;
 
 public class TestMyDetailsEdit extends ManagedTest {
@@ -22,81 +28,42 @@ public class TestMyDetailsEdit extends ManagedTest {
     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();
-        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);
-        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
-    public void testUnsetSuffix() throws IOException {
+    public void testDelName() throws IOException, GigiApiException {
+        User user = User.getById(id);
+        int startn = user.getNames().length;
         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
-    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 {
-        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);
@@ -108,6 +75,6 @@ public class TestMyDetailsEdit extends ManagedTest {
 
     @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);
-        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);
index ae89544f155c6a7de5756d429a47f01fc3ffddc9..bd64f9bf2e0da906ef282323ea588b0912eb7ad2 100644 (file)
@@ -31,11 +31,11 @@ public class TestSEAdminNotificationMail extends ClientTest {
     @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."));
-        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.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;
@@ -39,8 +38,8 @@ public class TestSEAdminPageDetails extends ClientTest {
         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));
     }
 
@@ -69,31 +68,6 @@ public class TestSEAdminPageDetails extends ClientTest {
         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";
@@ -105,29 +79,29 @@ public class TestSEAdminPageDetails extends ClientTest {
         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
-        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
-        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));
 
-        // 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
-        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) {
-        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);
@@ -162,12 +136,4 @@ public class TestSEAdminPageDetails extends ClientTest {
         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 int assureeName;
+
     private String cookie;
 
     @Before
@@ -41,7 +43,8 @@ public class TestAssurance extends ManagedTest {
         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);
     }
@@ -95,7 +98,7 @@ public class TestAssurance extends ManagedTest {
     @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"));
@@ -120,36 +123,25 @@ public class TestAssurance extends ManagedTest {
         assertEquals(500, uc.getResponseCode());
     }
 
-    @Test
-    public void testAssureFormRaceName() throws IOException, SQLException {
-        testAssureFormRace(true, false);
-    }
-
     @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 {
-        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);
-        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) {
@@ -231,7 +223,7 @@ public class TestAssurance extends ManagedTest {
 
     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);
     }
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.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;
@@ -118,17 +119,14 @@ public abstract class BusinessTest extends ConfiguredTest {
         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 {
-        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) {
@@ -137,6 +135,16 @@ public abstract class BusinessTest extends ConfiguredTest {
         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);
index e096be4c13e4599145095b27e536d82d6ede38b7..31c28686694aefbb722d3cbc787ad6dc29988287 100644 (file)
@@ -1,18 +1,22 @@
 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;
 
+    protected final Name n0;
+
     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);
         }
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.User;
 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);
-            ps2.setInt(2, uid);
+            ps2.setInt(2, User.getById(uid).getPreferredName().getId());
             ps2.execute();
         }
     }
index 477345f36e46bd3404732b76d635728752d8a864..21045c9a229b1ef1d87bc453dfb35c5f7d4856a7 100644 (file)
@@ -31,7 +31,7 @@ public class TestNotary extends BusinessTest {
         };
 
         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
@@ -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");
-            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");
         }
 
@@ -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 {
-            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
@@ -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) {
-                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");
         }
@@ -113,7 +113,7 @@ public class TestNotary extends BusinessTest {
         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");
index 254df05a70d5d612e6b755faf15aa26c2e7dea61..94c605915948b57651fdcb34502087432207dbfc 100644 (file)
@@ -2,19 +2,19 @@ package org.cacert.gigi.util;
 
 import static org.junit.Assert.*;
 
-import org.cacert.gigi.dbObjects.Name;
+import org.cacert.gigi.testUtils.ClientBusinessTest;
 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) {
-        return PasswordStrengthChecker.checkpw(pw, n, e);
+        return PasswordStrengthChecker.checkpw(pw, new String[] {
+                "fname", "lname", "mname", "suffix"
+        }, e);
     }
 
     @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.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;
@@ -203,7 +204,9 @@ public class Manager extends Page {
         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);
     }
@@ -269,7 +272,7 @@ public class Manager extends Page {
             }
             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);
@@ -281,7 +284,7 @@ public class Manager extends Page {
             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);