add: allow manually triggered email reping. (addresses #5)
authorFelix Dörre <felix@dogcraft.de>
Tue, 14 Jun 2016 08:16:21 +0000 (10:16 +0200)
committerFelix Dörre <felix@dogcraft.de>
Thu, 16 Jun 2016 09:58:20 +0000 (11:58 +0200)
Change-Id: I13853b13de25a4f7257929bad987a9d4e9f0b5ab

src/org/cacert/gigi/database/DatabaseConnection.java
src/org/cacert/gigi/database/tableStructure.sql
src/org/cacert/gigi/database/upgrade/from_9.sql [new file with mode: 0644]
src/org/cacert/gigi/dbObjects/EmailAddress.java
src/org/cacert/gigi/pages/account/mail/MailManagementForm.java
src/org/cacert/gigi/pages/account/mail/MailManagementForm.templ
src/org/cacert/gigi/pages/account/mail/MailOverview.java
tests/org/cacert/gigi/pages/account/TestMailManagement.java
util-testing/org/cacert/gigi/pages/Manager.java

index c85b5348d6e253c2dd96d1219723b9913751db23..f1c1c01102e126677e373c42edc864270c512de6 100644 (file)
@@ -99,7 +99,7 @@ public class DatabaseConnection {
 
     }
 
-    public static final int CURRENT_SCHEMA_VERSION = 9;
+    public static final int CURRENT_SCHEMA_VERSION = 10;
 
     public static final int CONNECTION_TIMEOUT = 24 * 60 * 60;
 
@@ -222,12 +222,7 @@ public class DatabaseConnection {
             Statement s = getInstance().c.createStatement();
             try {
                 while (version < CURRENT_SCHEMA_VERSION) {
-                    try (InputStream resourceAsStream = DatabaseConnection.class.getResourceAsStream("upgrade/from_" + version + ".sql")) {
-                        if (resourceAsStream == null) {
-                            throw new Error("Upgrade script from version " + version + " was not found.");
-                        }
-                        SQLFileManager.addFile(s, resourceAsStream, ImportType.PRODUCTION);
-                    }
+                    addUpgradeScript(Integer.toString(version), s);
                     version++;
                 }
                 s.addBatch("UPDATE \"schemeVersion\" SET version='" + version + "'");
@@ -244,6 +239,15 @@ public class DatabaseConnection {
         }
     }
 
+    private static void addUpgradeScript(String version, Statement s) throws Error, IOException, SQLException {
+        try (InputStream resourceAsStream = DatabaseConnection.class.getResourceAsStream("upgrade/from_" + version + ".sql")) {
+            if (resourceAsStream == null) {
+                throw new Error("Upgrade script from version " + version + " was not found.");
+            }
+            SQLFileManager.addFile(s, resourceAsStream, ImportType.PRODUCTION);
+        }
+    }
+
     public static final String preprocessQuery(String originalQuery) {
         originalQuery = originalQuery.replace('`', '"');
         if (originalQuery.matches("^INSERT INTO [^ ]+ SET .*")) {
index e49b84af15a29a587e2733eedeba3c18ab33afe6..e7859420e39a3030635c0801d5ca6d58ae5f3c6c 100644 (file)
@@ -67,12 +67,9 @@ CREATE TABLE "emails" (
   "created" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
   "modified" timestamp NULL DEFAULT NULL,
   "deleted" timestamp NULL DEFAULT NULL,
-  "hash" varchar(50) NOT NULL DEFAULT '',
-  "attempts" smallint NOT NULL DEFAULT '0',
   PRIMARY KEY ("id")
 );
 CREATE INDEX ON "emails" ("memid");
-CREATE INDEX ON "emails" ("hash");
 CREATE INDEX ON "emails" ("deleted");
 CREATE INDEX ON "emails" ("email");
 
@@ -90,7 +87,8 @@ CREATE TABLE "emailPinglog" (
   "email" varchar(255) NOT NULL,
   "type" "emailPingType" NOT NULL,
   "status" "pingState" NOT NULL,
-  "result" varchar(255) NOT NULL
+  "result" varchar(255) NOT NULL,
+  "challenge" varchar(255) NULL DEFAULT NULL
 );
 
 DROP TABLE IF EXISTS "pingconfig";
@@ -374,7 +372,7 @@ CREATE TABLE "schemeVersion" (
   "version" smallint NOT NULL,
   PRIMARY KEY ("version")
 );
-INSERT INTO "schemeVersion" (version)  VALUES(9);
+INSERT INTO "schemeVersion" (version)  VALUES(10);
 
 DROP TABLE IF EXISTS `passwordResetTickets`;
 CREATE TABLE `passwordResetTickets` (
diff --git a/src/org/cacert/gigi/database/upgrade/from_9.sql b/src/org/cacert/gigi/database/upgrade/from_9.sql
new file mode 100644 (file)
index 0000000..ec2b0be
--- /dev/null
@@ -0,0 +1,5 @@
+ALTER TABLE "emailPinglog" ADD COLUMN "challenge" varchar(255) NULL DEFAULT NULL;
+
+INSERT INTO "emailPinglog" SELECT CURRENT_TIMESTAMP AS "when", "memid" AS "uid", "email", 'active'::"emailPingType" AS "type", CASE WHEN "hash"='' THEN 'success'::"pingState" ELSE 'open'::"pingState" END AS state, '' AS result, "hash" AS "challenge" FROM "emails";
+ALTER TABLE "emails" DROP COLUMN "attempts";
+ALTER TABLE "emails" DROP COLUMN "hash";
index 7a053201c0cf6e1cc4a46d20202f297ffd8e5915..d92338ca9899f0dc8e126159e005e26863cd0b88 100644 (file)
@@ -1,7 +1,11 @@
 package org.cacert.gigi.dbObjects;
 
 import java.io.IOException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
 import java.util.Locale;
+import java.util.Map;
 
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.database.GigiPreparedStatement;
@@ -9,20 +13,22 @@ import org.cacert.gigi.database.GigiResultSet;
 import org.cacert.gigi.email.EmailProvider;
 import org.cacert.gigi.email.MailProbe;
 import org.cacert.gigi.localisation.Language;
+import org.cacert.gigi.output.template.Scope;
+import org.cacert.gigi.output.template.SprintfCommand;
 import org.cacert.gigi.util.RandomToken;
 
 public class EmailAddress implements IdCachable, Verifyable {
 
+    public static final int REPING_MINIMUM_DELAY = 5 * 60 * 1000;
+
     private String address;
 
     private int id;
 
     private User owner;
 
-    private String hash = null;
-
     private EmailAddress(int id) {
-        try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT `memid`, `email`, `hash` FROM `emails` WHERE `id`=? AND `deleted` IS NULL")) {
+        try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT `memid`, `email` FROM `emails` WHERE `id`=? AND `deleted` IS NULL")) {
             ps.setInt(1, id);
 
             GigiResultSet rs = ps.executeQuery();
@@ -32,7 +38,6 @@ public class EmailAddress implements IdCachable, Verifyable {
             this.id = id;
             owner = User.getById(rs.getInt(1));
             address = rs.getString(2);
-            hash = rs.getString(3);
         }
     }
 
@@ -42,7 +47,6 @@ public class EmailAddress implements IdCachable, Verifyable {
         }
         this.address = address;
         this.owner = owner;
-        this.hash = RandomToken.generateToken(16);
         insert(Language.getInstance(mailLocale));
     }
 
@@ -52,10 +56,9 @@ public class EmailAddress implements IdCachable, Verifyable {
                 if (id != 0) {
                     throw new IllegalStateException("already inserted.");
                 }
-                try (GigiPreparedStatement psCheck = new GigiPreparedStatement("SELECT 1 FROM `emails` WHERE email=? AND deleted is NULL"); GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `emails` SET memid=?, hash=?, email=?")) {
+                try (GigiPreparedStatement psCheck = new GigiPreparedStatement("SELECT 1 FROM `emails` WHERE email=? AND deleted is NULL"); GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `emails` SET memid=?, email=?")) {
                     ps.setInt(1, owner.getId());
-                    ps.setString(2, hash);
-                    ps.setString(3, address);
+                    ps.setString(2, address);
                     psCheck.setString(1, address);
                     GigiResultSet res = psCheck.executeQuery();
                     if (res.next()) {
@@ -66,12 +69,24 @@ public class EmailAddress implements IdCachable, Verifyable {
                 }
                 myCache.put(this);
             }
-            MailProbe.sendMailProbe(l, "email", id, hash, address);
+            ping(l);
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 
+    private void ping(Language l) throws IOException {
+        String hash = RandomToken.generateToken(16);
+        try (GigiPreparedStatement statmt = new GigiPreparedStatement("INSERT INTO `emailPinglog` SET `when`=NOW(), `email`=?, `result`='', `uid`=?, `type`='active', `status`='open'::`pingState`, `challenge`=?")) {
+            statmt.setString(1, address);
+            statmt.setInt(2, owner.getId());
+            statmt.setString(3, hash);
+            statmt.execute();
+        }
+
+        MailProbe.sendMailProbe(l, "email", id, hash, address);
+    }
+
     public int getId() {
         return id;
     }
@@ -81,28 +96,53 @@ public class EmailAddress implements IdCachable, Verifyable {
     }
 
     public synchronized void verify(String hash) throws GigiApiException {
-        if (this.hash.equals(hash)) {
-            try (GigiPreparedStatement ps = new GigiPreparedStatement("UPDATE `emails` SET hash='' WHERE id=?")) {
-                ps.setInt(1, id);
-                ps.execute();
-            }
-            hash = "";
+        try (GigiPreparedStatement stmt = new GigiPreparedStatement("UPDATE `emailPinglog` SET `status`='success'::`pingState` WHERE `email`=? AND `uid`=? AND `type`='active' AND `challenge`=?")) {
+            stmt.setString(1, address);
+            stmt.setInt(2, owner.getId());
+            stmt.setString(3, hash);
+            stmt.executeUpdate();
+        }
+        // Verify user with that primary email
+        try (GigiPreparedStatement ps2 = new GigiPreparedStatement("update `users` set `verified`='1' where `id`=? and `email`=? and `verified`='0'")) {
+            ps2.setInt(1, owner.getId());
+            ps2.setString(2, address);
+            ps2.execute();
+        }
+    }
 
-            // Verify user with that primary email
-            try (GigiPreparedStatement ps2 = new GigiPreparedStatement("update `users` set `verified`='1' where `id`=? and `email`=? and `verified`='0'")) {
-                ps2.setInt(1, owner.getId());
-                ps2.setString(2, address);
-                ps2.execute();
-            }
-            this.hash = "";
+    public boolean isVerified() {
+        try (GigiPreparedStatement statmt = new GigiPreparedStatement("SELECT 1 FROM `emailPinglog` WHERE `email`=? AND `uid`=? AND `type`='active' AND `status`='success'")) {
+            statmt.setString(1, address);
+            statmt.setInt(2, owner.getId());
+            GigiResultSet e = statmt.executeQuery();
+            return e.next();
+        }
+    }
 
-        } else {
-            throw new GigiApiException("Email verification hash is invalid.");
+    public Date getLastPing(boolean onlySuccess) {
+        Date lastExecution;
+        try (GigiPreparedStatement statmt = new GigiPreparedStatement("SELECT MAX(`when`) FROM `emailPinglog` WHERE `email`=? AND `uid`=? AND `type`='active'" + (onlySuccess ? " AND `status`='success'" : ""))) {
+            statmt.setString(1, address);
+            statmt.setInt(2, owner.getId());
+            GigiResultSet e = statmt.executeQuery();
+            if ( !e.next()) {
+                return null;
+            }
+            lastExecution = e.getTimestamp(1);
         }
+        return lastExecution;
     }
 
-    public boolean isVerified() {
-        return hash.isEmpty();
+    public synchronized void requestReping(Language l) throws IOException, GigiApiException {
+        Date lastExecution = getLastPing(false);
+
+        if (lastExecution != null && lastExecution.getTime() + REPING_MINIMUM_DELAY >= System.currentTimeMillis()) {
+            Map<String, Object> data = new HashMap<String, Object>();
+            data.put("data", new Date(lastExecution.getTime() + REPING_MINIMUM_DELAY));
+            throw new GigiApiException(new Scope(new SprintfCommand("Reping is only allowed after 5 minutes, yours end at {0}.", Arrays.asList("${data}")), data));
+        }
+        ping(l);
+        return;
     }
 
     private static ObjectCache<EmailAddress> myCache = new ObjectCache<>();
index c8245026d8d6b8a0e47f0251e497318f758de6ab..c082a1be509743ab9b09963a0c2104a0966d0b69 100644 (file)
@@ -1,7 +1,9 @@
 package org.cacert.gigi.pages.account.mail;
 
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import javax.servlet.http.HttpServletRequest;
 
@@ -30,36 +32,29 @@ public class MailManagementForm extends Form {
 
     @Override
     public boolean submit(PrintWriter out, HttpServletRequest req) {
-        if (req.getParameter("makedefault") != null) {
-            try {
-                String mailid = req.getParameter("emailid");
-                if (mailid == null) {
-                    return false;
+        Map<String, String[]> map = req.getParameterMap();
+        try {
+            for (Entry<String, String[]> e : map.entrySet()) {
+                String k = e.getKey();
+                String[] p = k.split(":", 2);
+                if (p[0].equals("default")) {
+                    target.updateDefaultEmail(EmailAddress.getById(Integer.parseInt(p[1])));
                 }
-                target.updateDefaultEmail(EmailAddress.getById(Integer.parseInt(mailid.trim())));
-            } catch (GigiApiException e) {
-                e.format(out, Page.getLanguage(req));
-                return false;
-            }
-            return true;
-        }
-        if (req.getParameter("delete") != null) {
-            String[] toDel = req.getParameterValues("delid[]");
-            if (toDel == null) {
-                return false;
-            }
-            for (int i = 0; i < toDel.length; i++) {
-                try {
-                    target.deleteEmail(EmailAddress.getById(Integer.parseInt(toDel[i].trim())));
-                } catch (GigiApiException e) {
-                    e.format(out, Page.getLanguage(req));
-                    return false;
+                if (p[0].equals("delete")) {
+                    target.deleteEmail(EmailAddress.getById(Integer.parseInt(p[1])));
+                }
+                if (p[0].equals("reping")) {
+                    EmailAddress.getById(Integer.parseInt(p[1])).requestReping(Page.getLanguage(req));
                 }
             }
-            return true;
-
+        } catch (GigiApiException e) {
+            e.format(out, Page.getLanguage(req));
+            return false;
+        } catch (IOException e1) {
+            new GigiApiException("Error while doing reping.").format(out, Page.getLanguage(req));
+            return false;
         }
-        return false;
+        return true;
     }
 
     @Override
@@ -78,9 +73,9 @@ public class MailManagementForm extends Form {
                 int mailID = emailAddress.getId();
                 vars.put("id", mailID);
                 if (emailAddress.getAddress().equals(target.getEmail())) {
-                    vars.put("checked", "checked");
+                    vars.put("default", " disabled");
                 } else {
-                    vars.put("checked", "");
+                    vars.put("default", "");
                 }
                 if (emailAddress.isVerified()) {
                     vars.put("verification", "Verified");
index 3b8d940043f4800cea1bc71350137b2b22f96d5e..6c6439bf1771fa084a16bcec6bd9d50b190de365 100644 (file)
@@ -8,20 +8,18 @@
   <tr>
     <td><?=_Default?></td>
     <td><?=_Status?></td>
-    <td><?=_Delete?></td>
     <td><?=_Address?></td>
+    <td><?=_Delete?></td>
+    <td><?=_Request reping?></td>
   </tr>
  <? foreach($emails) {?>
        <tr>
-               <td><input type="radio" name="emailid" value="<?=$id?>" <?=$!checked?>></td>
+               <td><input type="submit" name="default:<?=$id?>" value="<?=_Set as Default?>"<?=$default?>></td>
                <td><?=$verification?></td>
-               <td><?=$!delete?></td>
                <td><?=$address?></td>
+               <td><input type="submit" name="delete:<?=$id?>" value="<?=_Delete?>"<?=$default?>></td>
+               <td><input type="submit" name="reping:<?=$id?>" value="<?=_Request reping?>"></td>
        </tr>
  <? } ?>
-  <tr>
-    <td colspan="2"><input type="submit" name="makedefault" value="Setze als Standard"></td>
-    <td colspan="2"><input type="submit" name="delete" value="Löschen"></td>
-  </tr>
   </tbody>
 </table>
index e3b59916403ccbb64a933af0c3964acc6442aed0..da3befd581b214c57a284431de6e9b2d7d11d522 100644 (file)
@@ -39,7 +39,7 @@ public class MailOverview extends Page {
             if (f.submit(out, req)) {
                 resp.sendRedirect(MailOverview.DEFAULT_PATH);
             }
-        } else if (req.getParameter("makedefault") != null || req.getParameter("delete") != null) {
+        } else {
             MailManagementForm f = Form.getForm(req, MailManagementForm.class);
             if (f.submit(out, req)) {
                 resp.sendRedirect(MailOverview.DEFAULT_PATH);
index bf97c26964c5c7a697d8fd6309eb973757f313d2..412e2d78a1e98da97839fbd081b659b3777d50a2 100644 (file)
@@ -67,17 +67,17 @@ public class TestMailManagement extends ClientTest {
 
     @Test
     public void testMailSetDefaultWeb() throws MalformedURLException, UnsupportedEncodingException, IOException, InterruptedException, GigiApiException {
-        EmailAddress adrr = createVerifiedEmail(u);
-        assertNull(executeBasicWebInteraction(cookie, path, "makedefault&emailid=" + adrr.getId()));
+        EmailAddress addr = createVerifiedEmail(u);
+        assertNull(executeBasicWebInteraction(cookie, path, "default:" + addr.getId()));
         ObjectCache.clearAllCaches();
-        assertEquals(User.getById(u.getId()).getEmail(), adrr.getAddress());
+        assertEquals(User.getById(u.getId()).getEmail(), addr.getAddress());
     }
 
     @Test
     public void testMailSetDefaultWebUnverified() throws MalformedURLException, UnsupportedEncodingException, IOException, InterruptedException, GigiApiException {
-        EmailAddress adrr = new EmailAddress(u, createUniqueName() + "test@test.tld", Locale.ENGLISH);
-        assertNotNull(executeBasicWebInteraction(cookie, path, "makedefault&emailid=" + adrr.getId()));
-        assertNotEquals(User.getById(u.getId()).getEmail(), adrr.getAddress());
+        EmailAddress addr = new EmailAddress(u, createUniqueName() + "test@test.tld", Locale.ENGLISH);
+        assertNotNull(executeBasicWebInteraction(cookie, path, "default:" + addr.getId()));
+        assertNotEquals(User.getById(u.getId()).getEmail(), addr.getAddress());
         getMailReciever().clearMails();
     }
 
@@ -92,7 +92,7 @@ public class TestMailManagement extends ClientTest {
             }
         }
         assertNotEquals(id, -1);
-        assertNotNull(executeBasicWebInteraction(cookie, path, "makedefault&emailid=" + id));
+        assertNotNull(executeBasicWebInteraction(cookie, path, "default:" + id));
         assertNotEquals(User.getById(u.getId()).getEmail(), u2.getEmail());
         getMailReciever().clearMails();
     }
@@ -100,7 +100,7 @@ public class TestMailManagement extends ClientTest {
     @Test
     public void testMailDeleteWeb() throws InterruptedException, GigiApiException, MalformedURLException, UnsupportedEncodingException, IOException {
         EmailAddress addr = createVerifiedEmail(u);
-        assertNull(executeBasicWebInteraction(cookie, path, "delete&delid[]=" + addr.getId(), 0));
+        assertNull(executeBasicWebInteraction(cookie, path, "delete:" + addr.getId(), 0));
         User u = User.getById(this.u.getId());
         EmailAddress[] addresses = u.getEmails();
         for (int i = 0; i < addresses.length; i++) {
@@ -113,7 +113,7 @@ public class TestMailManagement extends ClientTest {
         EmailAddress[] addr = new EmailAddress[] {
                 createVerifiedEmail(u), createVerifiedEmail(u)
         };
-        assertNull(executeBasicWebInteraction(cookie, path, "delete&delid[]=" + addr[0].getId() + "&delid[]=" + addr[1].getId(), 0));
+        assertNull(executeBasicWebInteraction(cookie, path, "delete:" + addr[0].getId() + "&delete:" + addr[1].getId(), 0));
         User u = User.getById(this.u.getId());
         EmailAddress[] addresses = u.getEmails();
         for (int i = 0; i < addresses.length; i++) {
@@ -126,14 +126,14 @@ public class TestMailManagement extends ClientTest {
     public void testMailDeleteWebFaulty() throws MalformedURLException, UnsupportedEncodingException, IOException {
         User u2 = User.getById(createVerifiedUser("fn", "ln", createUniqueName() + "uni@test.tld", TEST_PASSWORD));
         EmailAddress em = u2.getEmails()[0];
-        assertNotNull(executeBasicWebInteraction(cookie, path, "delete&delid[]=" + em.getId(), 0));
+        assertNotNull(executeBasicWebInteraction(cookie, path, "delete:" + em.getId(), 0));
         u2 = User.getById(u2.getId());
         assertNotEquals(u2.getEmails().length, 0);
     }
 
     @Test
     public void testMailDeleteWebPrimary() throws MalformedURLException, UnsupportedEncodingException, IOException {
-        assertNotNull(executeBasicWebInteraction(cookie, path, "delete&delid[]=" + u.getEmails()[0].getId(), 0));
+        assertNotNull(executeBasicWebInteraction(cookie, path, "delete:" + u.getEmails()[0].getId(), 0));
         assertNotEquals(u.getEmails().length, 0);
     }
 }
index 460fc4d22ff13203831ba313e48b8e7a53b82059..649b7944ef99cf64f455bd0b03743de10ec65efe 100644 (file)
@@ -17,6 +17,8 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Properties;
 import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -53,20 +55,10 @@ public class Manager extends Page {
 
     public static final String PATH = "/manager";
 
-    Field f;
-
     private static HashMap<DomainPingType, DomainPinger> dps;
 
     private Manager() {
         super("Test Manager");
-        try {
-            f = EmailAddress.class.getDeclaredField("hash");
-            f.setAccessible(true);
-        } catch (ReflectiveOperationException e) {
-            // TODO
-            System.out.println("I don't have 'hash', we are working probably in layered mode. Test Manager may not work.");
-            // throw new Error(e);
-        }
 
         try {
             Field gigiInstance = Gigi.class.getDeclaredField("instance");
@@ -212,13 +204,21 @@ public class Manager extends Page {
         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);
         EmailAddress ea = u.getEmails()[0];
-        if (f == null) {
-            System.out.println("verification failed");
-            return;
-        }
-        String hash = (String) f.get(ea);
+        verify(email, ea);
+    }
 
-        ea.verify(hash);
+    private void verify(String email, EmailAddress ea) throws GigiApiException {
+        LinkedList<String> i = emails.get(email);
+        while (i.size() > 0 && !ea.isVerified()) {
+            String lst = i.getLast();
+            Pattern p = Pattern.compile("hash=([a-zA-Z0-9]+)");
+            Matcher m = p.matcher(lst);
+            if (m.find()) {
+                ea.verify(m.group(1));
+            }
+            i.removeLast();
+        }
+        // ea.verify(hash);
     }
 
     User[] assurers = new User[25];
@@ -283,19 +283,10 @@ public class Manager extends Page {
             User u = User.getByEmail(req.getParameter("addEmailEmail"));
             try {
                 EmailAddress ea = new EmailAddress(u, req.getParameter("addEmailNew"), Locale.ENGLISH);
-                if (f != null) {
-                    String hash = (String) f.get(ea);
-                    ea.verify(hash);
-                    resp.getWriter().println("Email added and verified");
-                } else {
-                    resp.getWriter().println("Email added but verificatio failed.");
-                }
+                verify(ea.getAddress(), ea);
             } catch (IllegalArgumentException e) {
                 e.printStackTrace();
                 resp.getWriter().println("An internal error occured.");
-            } catch (IllegalAccessException e) {
-                e.printStackTrace();
-                resp.getWriter().println("An internal error occured.");
             } catch (GigiApiException e) {
                 e.format(resp.getWriter(), Language.getInstance(Locale.ENGLISH));
             }