fix: error when adding Verifications Points via Test Manager
[gigi.git] / util-testing / club / wpia / gigi / pages / Manager.java
index af05ab4..f68d307 100644 (file)
@@ -7,6 +7,7 @@ import java.security.GeneralSecurityException;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.security.Signature;
+import java.sql.Timestamp;
 import java.text.SimpleDateFormat;
 import java.util.Base64;
 import java.util.Calendar;
@@ -31,31 +32,38 @@ import club.wpia.gigi.Gigi;
 import club.wpia.gigi.GigiApiException;
 import club.wpia.gigi.crypto.SPKAC;
 import club.wpia.gigi.database.GigiPreparedStatement;
+import club.wpia.gigi.database.GigiResultSet;
 import club.wpia.gigi.dbObjects.CATS;
+import club.wpia.gigi.dbObjects.CATS.CATSType;
 import club.wpia.gigi.dbObjects.Certificate;
+import club.wpia.gigi.dbObjects.Certificate.CertificateStatus;
 import club.wpia.gigi.dbObjects.CertificateOwner;
+import club.wpia.gigi.dbObjects.Contract;
+import club.wpia.gigi.dbObjects.Contract.ContractType;
 import club.wpia.gigi.dbObjects.Country;
 import club.wpia.gigi.dbObjects.Digest;
 import club.wpia.gigi.dbObjects.Domain;
+import club.wpia.gigi.dbObjects.DomainPingConfiguration;
+import club.wpia.gigi.dbObjects.DomainPingExecution;
 import club.wpia.gigi.dbObjects.DomainPingType;
 import club.wpia.gigi.dbObjects.EmailAddress;
 import club.wpia.gigi.dbObjects.Group;
 import club.wpia.gigi.dbObjects.NamePart;
-import club.wpia.gigi.dbObjects.User;
-import club.wpia.gigi.dbObjects.Assurance.AssuranceType;
-import club.wpia.gigi.dbObjects.CATS.CATSType;
-import club.wpia.gigi.dbObjects.Certificate.CertificateStatus;
 import club.wpia.gigi.dbObjects.NamePart.NamePartType;
+import club.wpia.gigi.dbObjects.User;
+import club.wpia.gigi.dbObjects.Verification.VerificationType;
 import club.wpia.gigi.email.DelegateMailProvider;
+import club.wpia.gigi.email.EmailProvider;
 import club.wpia.gigi.localisation.Language;
 import club.wpia.gigi.output.template.IterableDataset;
 import club.wpia.gigi.output.template.Template;
-import club.wpia.gigi.pages.Page;
 import club.wpia.gigi.pages.account.certs.CertificateRequest;
 import club.wpia.gigi.ping.DomainPinger;
 import club.wpia.gigi.ping.PingerDaemon;
 import club.wpia.gigi.util.AuthorizationContext;
 import club.wpia.gigi.util.DayDate;
+import club.wpia.gigi.util.DomainAssessment;
+import club.wpia.gigi.util.HTMLEncoder;
 import club.wpia.gigi.util.Notary;
 import club.wpia.gigi.util.TimeConditions;
 import sun.security.x509.X509Key;
@@ -110,7 +118,7 @@ public class Manager extends Page {
             return supporter;
         }
         try {
-            User u = createAssurer( -1);
+            User u = createAgent( -1);
             if ( !u.isInGroup(Group.SUPPORTER)) {
                 try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `user_groups` SET `user`=?, `permission`=?::`userGroup`, `grantedby`=?")) {
                     ps.setInt(1, u.getId());
@@ -127,29 +135,29 @@ public class Manager extends Page {
         return supporter;
     }
 
-    public User getAssurer(int i) {
-        if (assurers[i] != null) {
-            return assurers[i];
+    public User getAgent(int i) {
+        if (agents[i] != null) {
+            return agents[i];
         }
         try {
-            User u = createAssurer(i);
-            assurers[i] = u;
+            User u = createAgent(i);
+            agents[i] = u;
 
         } catch (ReflectiveOperationException | GigiApiException e) {
             e.printStackTrace();
         }
-        return assurers[i];
+        return agents[i];
     }
 
-    private User createAssurer(int i) throws GigiApiException, IllegalAccessException {
+    private User createAgent(int i) throws GigiApiException, IllegalAccessException {
         try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, `points`=?, `location`=?, `date`=?, `country`=?")) {
-            String mail = "test-assurer" + i + "@example.com";
+            String mail = "test-agent" + i + "@example.com";
             User u = User.getByEmail(mail);
             if (u == null) {
                 System.out.println("Creating RA-Agent");
                 createUser(mail);
                 u = User.getByEmail(mail);
-                passCATS(u, CATSType.ASSURER_CHALLENGE);
+                passCATS(u, CATSType.AGENT_CHALLENGE);
                 ps.setInt(1, u.getId());
                 ps.setInt(2, u.getPreferredName().getId());
                 ps.setInt(3, 100);
@@ -158,6 +166,7 @@ public class Manager extends Page {
                 ps.setString(6, getRandomCountry().getCode());
                 ps.execute();
             }
+            new Contract(u, ContractType.RA_AGENT_CONTRACT);
             return u;
         }
     }
@@ -166,6 +175,24 @@ public class Manager extends Page {
         CATS.enterResult(u, t, new Date(System.currentTimeMillis()), "en_EN", "1");
     }
 
+    private void expireCATS(User u, CATSType t) {
+        try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT `id` FROM `cats_passed` WHERE `user_id`=? AND `variant_id`=? AND `pass_date`>?")) {
+            ps.setInt(1, u.getId());
+            ps.setInt(2, t.getId());
+            ps.setTimestamp(3, new Timestamp(System.currentTimeMillis() - DayDate.MILLI_DAY * 366));
+            ps.execute();
+            GigiResultSet rs = ps.executeQuery();
+            while (rs.next()) {
+                GigiPreparedStatement ps1 = new GigiPreparedStatement("UPDATE `cats_passed` SET `pass_date`=? WHERE `id`=?");
+                ps1.setTimestamp(1, new Timestamp(System.currentTimeMillis() - DayDate.MILLI_DAY * 367));
+                ps1.setInt(2, rs.getInt(1));
+                ps1.execute();
+                ps1.close();
+            }
+        }
+
+    }
+
     private static Manager instance;
 
     private static final Template t = new Template(Manager.class.getResource("ManagerMails.templ"));
@@ -231,12 +258,14 @@ public class Manager extends Page {
         }
 
         @Override
-        public void ping(Domain domain, String configuration, CertificateOwner target, int confId) {
-            System.out.println("Test: " + domain);
+        public DomainPingExecution ping(Domain domain, String configuration, CertificateOwner target, DomainPingConfiguration conf) {
+            System.err.println("TestManager: " + domain.getSuffix());
             if (pingExempt.contains(domain.getSuffix())) {
-                enterPingResult(confId, DomainPinger.PING_SUCCEDED, "Succeeded by TestManager pass-by", null);
+                return enterPingResult(conf, DomainPinger.PING_SUCCEDED, "Succeeded by TestManager pass-by", null);
             } else {
-                dps.get(dpt).ping(domain, configuration, target, confId);
+                DomainPinger pinger = dps.get(dpt);
+                System.err.println("Forward to old pinger: " + pinger);
+                return pinger.ping(domain, configuration, target, conf);
             }
         }
 
@@ -290,15 +319,35 @@ public class Manager extends Page {
         // ea.verify(hash);
     }
 
-    User[] assurers = new User[25];
+    User[] agents = new User[25];
 
     User supporter;
 
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        AuthorizationContext sessionAc = (AuthorizationContext) req.getSession().getAttribute(Gigi.AUTH_CONTEXT);
         if (req.getParameter("create") != null) {
-            batchCreateUsers(req.getParameter("prefix"), req.getParameter("suffix"), Integer.parseInt(req.getParameter("amount")), resp.getWriter());
-            resp.getWriter().println("User batch created.");
+            String prefix = req.getParameter("prefix");
+            String domain = req.getParameter("suffix");
+            try {
+                if (null == prefix) {
+                    throw new GigiApiException("No prefix given.");
+                }
+                if (null == domain) {
+                    throw new GigiApiException("No domain given.");
+                }
+
+                DomainAssessment.checkCertifiableDomain(domain, false, true);
+
+                if ( !EmailProvider.isValidMailAddress(prefix + "@" + domain)) {
+                    throw new GigiApiException("Invalid email address template.");
+                }
+
+                batchCreateUsers(prefix, domain, Integer.parseInt(req.getParameter("amount")), resp.getWriter());
+                resp.getWriter().println("User batch created.");
+            } catch (GigiApiException e) {
+                throw new Error(e);
+            }
         } else if (req.getParameter("addpriv") != null || req.getParameter("delpriv") != null) {
             User u = User.getByEmail(req.getParameter("email"));
             if (u == null) {
@@ -334,8 +383,23 @@ public class Manager extends Page {
             CATSType test = CATSType.values()[Integer.parseInt(testId)];
             passCATS(byEmail, test);
             resp.getWriter().println("Test '" + test.getDisplayName() + "' was added to user account.");
-        } else if (req.getParameter("assure") != null) {
-            String mail = req.getParameter("assureEmail");
+        } else if (req.getParameter("catsexpire") != null) {
+            String mail = req.getParameter("catsEmail");
+            String testId = req.getParameter("catsType");
+            User byEmail = User.getByEmail(mail);
+            if (byEmail == null) {
+                resp.getWriter().println("User not found.");
+                return;
+            }
+            if (testId == null) {
+                resp.getWriter().println("No test given.");
+                return;
+            }
+            CATSType test = CATSType.values()[Integer.parseInt(testId)];
+            expireCATS(byEmail, test);
+            resp.getWriter().println("Test '" + test.getDisplayName() + "' is set expired for user account.");
+        } else if (req.getParameter("verify") != null) {
+            String mail = req.getParameter("verifyEmail");
             String verificationPoints = req.getParameter("verificationPoints");
             User byEmail = User.getByEmail(mail);
 
@@ -345,45 +409,59 @@ public class Manager extends Page {
             }
 
             int vp = 0;
-            int agentNumber = 0;
+            int verifications = 0;
+            String info = "";
 
             try {
                 try {
                     vp = Integer.parseInt(verificationPoints);
                 } catch (NumberFormatException e) {
-                    throw new GigiApiException("No valid Verification Points entered.");
+                    resp.getWriter().println("The value for Verification Points must be an integer.</br>");
+                    vp = 0;
                 }
 
-                if (vp > 100) { // only allow max 100 Verification points
-                    vp = 100;
-                }
+                int agentNumber = addVerificationPoints(vp, byEmail);
 
                 while (vp > 0) {
                     int currentVP = 10;
                     if (vp < 10) {
                         currentVP = vp;
                     }
-                    Notary.assure(getAssurer(agentNumber), byEmail, byEmail.getPreferredName(), byEmail.getDoB(), currentVP, "Testmanager Verify up code", validVerificationDateString(), AssuranceType.FACE_TO_FACE, getRandomCountry());
+                    if (Notary.checkVerificationIsPossible(getAgent(agentNumber), byEmail.getPreferredName())) {
+
+                        Notary.verify(getAgent(agentNumber), byEmail, byEmail.getPreferredName(), byEmail.getDoB(), currentVP, "Testmanager Verify up code", validVerificationDateString(), VerificationType.FACE_TO_FACE, getRandomCountry());
+                        vp -= currentVP;
+                        verifications += 1;
+
+                    }
                     agentNumber += 1;
-                    vp -= currentVP;
+                    if (agentNumber >= agents.length) {
+                        info = "<br/>The limit of agents is reached. You cannot add any more Verification Points to the preferred name of this user using this method.";
+                        break;
+                    }
                 }
 
             } catch (GigiApiException e) {
                 throw new Error(e);
             }
 
-            resp.getWriter().println("User has been assured " + agentNumber + " times.");
+            resp.getWriter().println("User has been verified " + verifications + " times." + info);
 
-        } else if (req.getParameter("letassure") != null) {
-            String mail = req.getParameter("letassureEmail");
+        } else if (req.getParameter("letverify") != null) {
+            String mail = req.getParameter("letverifyEmail");
             User byEmail = User.getByEmail(mail);
-            try {
-                for (int i = 0; i < 25; i++) {
-                    User a = getAssurer(i);
-                    Notary.assure(byEmail, a, a.getNames()[0], a.getDoB(), 10, "Testmanager exp up code", validVerificationDateString(), AssuranceType.FACE_TO_FACE, getRandomCountry());
+            if (byEmail == null || !byEmail.canVerify()) {
+                resp.getWriter().println("User not found, or found user is not allowed to verify.");
+            } else {
+                try {
+                    for (int i = 0; i < 25; i++) {
+                        User a = getAgent(i);
+                        Notary.verify(byEmail, a, a.getNames()[0], a.getDoB(), 10, "Testmanager exp up code", validVerificationDateString(), VerificationType.FACE_TO_FACE, getRandomCountry());
+                    }
+                    resp.getWriter().println("Successfully added experience points.");
+                } catch (GigiApiException e) {
+                    throw new Error(e);
                 }
-            } catch (GigiApiException e) {
-                throw new Error(e);
             }
         } else if (req.getParameter("addEmail") != null) {
             User u = User.getByEmail(req.getParameter("addEmailEmail"));
@@ -394,7 +472,7 @@ public class Manager extends Page {
                 e.printStackTrace();
                 resp.getWriter().println("An internal error occured.");
             } catch (GigiApiException e) {
-                e.format(resp.getWriter(), Language.getInstance(Locale.ENGLISH));
+                e.format(resp.getWriter(), Language.getInstance(Locale.ENGLISH), getDefaultVars(req));
             }
         } else if (req.getParameter("addCert") != null) {
             User u = User.getByEmail(req.getParameter("addCertEmail"));
@@ -402,13 +480,13 @@ public class Manager extends Page {
                 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
                 kpg.initialize(4096);
                 KeyPair kp = kpg.generateKeyPair();
-                SPKAC s = new SPKAC((X509Key) kp.getPublic(), "challange");
+                SPKAC s = new SPKAC((X509Key) kp.getPublic(), "challenge");
                 Signature sign = Signature.getInstance("SHA512withRSA");
                 sign.initSign(kp.getPrivate());
 
                 byte[] res = s.getEncoded(sign);
 
-                CertificateRequest cr = new CertificateRequest(new AuthorizationContext(u, u), Base64.getEncoder().encodeToString(res), "challange");
+                CertificateRequest cr = new CertificateRequest(new AuthorizationContext(u, u, sessionAc.isStronglyAuthenticated()), Base64.getEncoder().encodeToString(res), "challenge");
                 cr.update(CertificateRequest.DEFAULT_CN, Digest.SHA512.toString(), "client", null, "", "email:" + u.getEmail());
                 Certificate draft = cr.draft();
                 draft.issue(null, "2y", u).waitFor(10000);
@@ -421,20 +499,65 @@ public class Manager extends Page {
                 e1.printStackTrace();
                 resp.getWriter().println("error");
             } catch (GigiApiException e) {
-                e.format(resp.getWriter(), Language.getInstance(Locale.ENGLISH));
+                e.format(resp.getWriter(), Language.getInstance(Locale.ENGLISH), getDefaultVars(req));
             }
 
         } else if (req.getParameter("addExDom") != null) {
-            String dom = req.getParameter("exemtDom");
+            String dom = req.getParameter("exemptDom");
             pingExempt.add(dom);
             resp.getWriter().println("Updated domains exempt from pings. Current set: <br/>");
-            resp.getWriter().println(pingExempt);
+            resp.getWriter().println(HTMLEncoder.encodeHTML(pingExempt.toString()));
         } else if (req.getParameter("delExDom") != null) {
-            String dom = req.getParameter("exemtDom");
+            String dom = req.getParameter("exemptDom");
             pingExempt.remove(dom);
             resp.getWriter().println("Updated domains exempt from pings. Current set: <br/>");
-            resp.getWriter().println(pingExempt);
+            resp.getWriter().println(HTMLEncoder.encodeHTML(pingExempt.toString()));
+        } else if (req.getParameter("makeAgent") != null) {
+            User u = User.getByEmail(req.getParameter("agentEmail"));
+            if (u == null) {
+                resp.getWriter().println("User not found, or found user is not allowed to verify.");
+            } else {
+                if (u.getVerificationPoints() < 100) {
+                    addVerificationPoints(100, u);
+                }
+                if ( !u.hasPassedCATS()) {
+                    passCATS(u, CATSType.AGENT_CHALLENGE);
+                }
+                if ( !Contract.hasSignedContract(u, Contract.ContractType.RA_AGENT_CONTRACT)) {
+                    try {
+                        new Contract(u, Contract.ContractType.RA_AGENT_CONTRACT);
+                    } catch (GigiApiException e) {
+                        throw new Error(e);
+                    }
+                }
+                resp.getWriter().println("User has all requirements to be an RA Agent");
+            }
+        }
+        resp.getWriter().println("<br/><a href='" + PATH + "'>Go back</a>");
+    }
+
+    private int addVerificationPoints(int vp, User byEmail) throws Error {
+        int agentNumber = 0;
+
+        try {
+            if (vp > 100) { // only allow max 100 Verification points
+                vp = 100;
+            }
+
+            while (vp > 0) {
+                int currentVP = 10;
+                if (vp < 10) {
+                    currentVP = vp;
+                }
+                Notary.verify(getAgent(agentNumber), byEmail, byEmail.getPreferredName(), byEmail.getDoB(), currentVP, "Testmanager Verify up code", validVerificationDateString(), VerificationType.FACE_TO_FACE, getRandomCountry());
+                agentNumber += 1;
+                vp -= currentVP;
+            }
+
+        } catch (GigiApiException e) {
+            throw new Error(e);
         }
+        return agentNumber;
     }
 
     private void fetchMails(HttpServletRequest req, HttpServletResponse resp, String mail) throws IOException {