]> WPIA git - gigi.git/commitdiff
Merge "upd: native Makefile improvements"
authorFelix Dörre <felix@dogcraft.de>
Wed, 14 Sep 2016 19:45:01 +0000 (21:45 +0200)
committerGerrit Code Review <gigi-system@dogcraft.de>
Wed, 14 Sep 2016 19:45:01 +0000 (21:45 +0200)
68 files changed:
debian/gigi-standalone.service
src/org/cacert/gigi/Gigi.java
src/org/cacert/gigi/api/CATSResolve.java
src/org/cacert/gigi/dbObjects/CertificateOwner.java
src/org/cacert/gigi/dbObjects/SupportedUser.java
src/org/cacert/gigi/output/template/Form.java
src/org/cacert/gigi/pages/LoginPage.java
src/org/cacert/gigi/pages/ManagedFormPage.java [new file with mode: 0644]
src/org/cacert/gigi/pages/ManagedMultiFormPage.java [new file with mode: 0644]
src/org/cacert/gigi/pages/OneFormPage.java
src/org/cacert/gigi/pages/Page.java
src/org/cacert/gigi/pages/PasswordResetPage.java
src/org/cacert/gigi/pages/Verify.java
src/org/cacert/gigi/pages/account/ChangeForm.java
src/org/cacert/gigi/pages/account/ChangePasswordPage.java
src/org/cacert/gigi/pages/account/FindAgentAccess.java
src/org/cacert/gigi/pages/account/MyDetails.java
src/org/cacert/gigi/pages/account/MyDetailsForm.java
src/org/cacert/gigi/pages/account/MyOrganisationsForm.java
src/org/cacert/gigi/pages/account/certs/CertificateAdd.java
src/org/cacert/gigi/pages/account/certs/CertificateDisplay.templ
src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.java
src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.templ
src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java
src/org/cacert/gigi/pages/account/certs/Certificates.java
src/org/cacert/gigi/pages/account/certs/RequestCertificate.templ
src/org/cacert/gigi/pages/account/certs/RevokeSingleCertForm.java
src/org/cacert/gigi/pages/account/domain/DomainAddForm.java
src/org/cacert/gigi/pages/account/domain/DomainManagementForm.java
src/org/cacert/gigi/pages/account/domain/DomainOverview.java
src/org/cacert/gigi/pages/account/domain/DomainPinglogForm.java
src/org/cacert/gigi/pages/account/domain/EditDomain.java [new file with mode: 0644]
src/org/cacert/gigi/pages/account/domain/PingConfigForm.java
src/org/cacert/gigi/pages/account/mail/MailAddForm.java
src/org/cacert/gigi/pages/account/mail/MailManagementForm.java
src/org/cacert/gigi/pages/account/mail/MailOverview.java
src/org/cacert/gigi/pages/admin/TTPAdminForm.java
src/org/cacert/gigi/pages/admin/TTPAdminPage.java
src/org/cacert/gigi/pages/admin/support/FindCertForm.java
src/org/cacert/gigi/pages/admin/support/FindCertPage.java
src/org/cacert/gigi/pages/admin/support/FindUserByDomainForm.java
src/org/cacert/gigi/pages/admin/support/FindUserByDomainPage.java
src/org/cacert/gigi/pages/admin/support/FindUserByEmailForm.java
src/org/cacert/gigi/pages/admin/support/FindUserByEmailPage.java
src/org/cacert/gigi/pages/admin/support/SupportEnterTicketForm.java
src/org/cacert/gigi/pages/admin/support/SupportEnterTicketPage.java
src/org/cacert/gigi/pages/admin/support/SupportRevokeCertificatesForm.java
src/org/cacert/gigi/pages/admin/support/SupportUserDetailsForm.java
src/org/cacert/gigi/pages/admin/support/SupportUserDetailsPage.java
src/org/cacert/gigi/pages/main/RegisterPage.java
src/org/cacert/gigi/pages/main/Signup.java
src/org/cacert/gigi/pages/orga/AffiliationForm.java
src/org/cacert/gigi/pages/orga/CreateOrgForm.java
src/org/cacert/gigi/pages/orga/CreateOrgPage.java
src/org/cacert/gigi/pages/orga/OrgDomainAddForm.java
src/org/cacert/gigi/pages/orga/ViewOrgPage.java
src/org/cacert/gigi/pages/wot/AssuranceForm.java
src/org/cacert/gigi/pages/wot/AssurePage.java
src/org/cacert/gigi/pages/wot/RequestTTPForm.java
src/org/cacert/gigi/pages/wot/RequestTTPPage.java
src/org/cacert/gigi/util/VerificationAgentEntered.templ
static/static/css/main.css
static/static/js/expert.js
tests/org/cacert/gigi/pages/account/TestCertificateAdd.java
tests/org/cacert/gigi/testUtils/ManagedTest.java
tests/org/cacert/gigi/testUtils/PingTest.java
util-testing/org/cacert/gigi/localisation/conf.txt
util-testing/org/cacert/gigi/util/SimpleSigner.java

index e60e2eedf7620604f96797e51372d8c3f2f5ab33..776625f823b15cc026dafbec93dbb5c028adcad3 100644 (file)
@@ -6,7 +6,7 @@ Conflicts=gigi-proxy.service
 
 [Service]
 ExecStart=/usr/bin/java -cp /usr/share/java/postgresql-jdbc4.jar:/usr/share/java/gigi.jar org.cacert.gigi.Launcher /etc/cacert/gigi/conf.tar
-CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETUID
+CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETUID CAP_SETGID
 WorkingDirectory=/var/lib/cacert-gigi
 PrivateTmp=yes
 PrivateDevices=yes
index afe6bcb72e86f787f37c89cb1cbc00294a08574b..23f10df990b812243f1644f6e5cb06584d5c2e5a 100644 (file)
@@ -32,7 +32,6 @@ import org.cacert.gigi.output.MenuCollector;
 import org.cacert.gigi.output.PageMenuItem;
 import org.cacert.gigi.output.SimpleMenuItem;
 import org.cacert.gigi.output.SimpleUntranslatedMenuItem;
-import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.Form.CSRFException;
 import org.cacert.gigi.output.template.Outputable;
 import org.cacert.gigi.output.template.Template;
@@ -56,6 +55,7 @@ import org.cacert.gigi.pages.account.UserTrainings;
 import org.cacert.gigi.pages.account.certs.CertificateAdd;
 import org.cacert.gigi.pages.account.certs.Certificates;
 import org.cacert.gigi.pages.account.domain.DomainOverview;
+import org.cacert.gigi.pages.account.domain.EditDomain;
 import org.cacert.gigi.pages.account.mail.MailOverview;
 import org.cacert.gigi.pages.admin.TTPAdminPage;
 import org.cacert.gigi.pages.admin.support.FindCertPage;
@@ -145,7 +145,8 @@ public final class Gigi extends HttpServlet {
             putPage(RegisterPage.PATH, new RegisterPage(), "SomeCA.org");
             putPage(CertificateAdd.PATH, new CertificateAdd(), "Certificates");
             putPage(MailOverview.DEFAULT_PATH, new MailOverview(), "Certificates");
-            putPage(DomainOverview.PATH + "*", new DomainOverview(), "Certificates");
+            putPage(DomainOverview.PATH, new DomainOverview(), "Certificates");
+            putPage(EditDomain.PATH + "*", new EditDomain(), null);
 
             putPage(AssurePage.PATH + "/*", new AssurePage(), "Web of Trust");
             putPage(Points.PATH, new Points(false), "Web of Trust");
@@ -163,13 +164,7 @@ public final class Gigi extends HttpServlet {
             putPage(SupportUserDetailsPage.PATH + "*", new SupportUserDetailsPage(), null);
             putPage(ChangePasswordPage.PATH, new ChangePasswordPage(), "My Account");
             putPage(History.PATH, new History(false), "My Account");
-            putPage(FindAgentAccess.PATH, new OneFormPage("Access to Find Agent", FindAgentAccess.class) {
-
-                @Override
-                public String getSuccessPath(Form f) {
-                    return FindAgentAccess.PATH;
-                }
-            }, "My Account");
+            putPage(FindAgentAccess.PATH, new OneFormPage("Access to Find Agent", FindAgentAccess.class), "My Account");
             putPage(History.SUPPORT_PATH, new History(true), null);
             putPage(UserTrainings.PATH, new UserTrainings(false), "My Account");
             putPage(MyDetails.PATH, new MyDetails(), "My Account");
index 1b25e9d5dd241c49d8e04f94272ad9b505ff1670..0e9f2a01e08bfc71f8a7760e0485d256936d02ba 100644 (file)
@@ -29,7 +29,7 @@ public class CATSResolve extends APIPoint {
             return;
         }
 
-        CertificateOwner o = CertificateOwner.getByEnabledSerial(target);
+        CertificateOwner o = CertificateOwner.getByEnabledSerial(target.toLowerCase());
         if ( !(o instanceof User)) {
             resp.sendError(500, "Error, requires valid serial");
             return;
index cc96ade7c39a5f3e532986cf3ed68a5378f0f24b..ab854bccd1e0dd40eab1b9b17a8cb5e7f8b07b9c 100644 (file)
@@ -127,7 +127,7 @@ public abstract class CertificateOwner implements IdCachable, Serializable {
 
     public static CertificateOwner getByEnabledSerial(String serial) {
         try (GigiPreparedStatement prep = new GigiPreparedStatement("SELECT `memid` FROM `certs` INNER JOIN `logincerts` ON `logincerts`.`id`=`certs`.`id` WHERE serial=? AND `revoked` is NULL")) {
-            prep.setString(1, serial.toLowerCase());
+            prep.setString(1, serial);
             GigiResultSet res = prep.executeQuery();
             if (res.next()) {
                 return getById(res.getInt(1));
index 67b5e1199e2167da36278dfef0af200bbce082c3..e600b85bf2d2fca302375d18e06693e19108c056 100644 (file)
@@ -1,7 +1,6 @@
 package org.cacert.gigi.dbObjects;
 
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.util.HashMap;
 import java.util.Locale;
 
@@ -175,11 +174,11 @@ public class SupportedUser {
         }
     }
 
-    public void triggerPasswordReset(String aword, PrintWriter out, HttpServletRequest req) {
+    public void triggerPasswordReset(String aword, HttpServletRequest req) {
         Language l = Language.getInstance(target.getPreferredLocale());
         String method = l.getTranslation("A password reset was triggered. Please enter the required text sent to you by support on this page:");
         String subject = l.getTranslation("Password reset by support.");
-        PasswordResetPage.initPasswordResetProcess(out, target, req, aword, l, method, subject);
+        PasswordResetPage.initPasswordResetProcess(target, req, aword, l, method, subject);
         Outputable message = new TranslateCommand("A password reset was triggered and an email was sent to user.");
         sendSupportNotification(subject, message);
     }
index 1eb0efa04e5f8ca4a87fc906bf2906f3eb7d3a4d..82d9e60074542ce0900f313d346f3d91b96a1a7c 100644 (file)
@@ -6,11 +6,12 @@ import java.util.HashMap;
 import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.localisation.Language;
-import org.cacert.gigi.pages.LoginPage;
+import org.cacert.gigi.pages.Page;
 import org.cacert.gigi.util.RandomToken;
 
 /**
@@ -18,8 +19,79 @@ import org.cacert.gigi.util.RandomToken;
  */
 public abstract class Form implements Outputable {
 
+    public static class PermamentFormException extends RuntimeException {
+
+        public PermamentFormException(GigiApiException cause) {
+            super(cause);
+        }
+
+        @Override
+        public synchronized GigiApiException getCause() {
+            return (GigiApiException) super.getCause();
+        }
+    }
+
+    /**
+     * Encapsulates a (non-failure) outcome of a form.
+     */
+    public static abstract class SubmissionResult {
+
+        public abstract boolean endsForm();
+    }
+
+    /**
+     * The form has finished and the user should see the successful completion
+     * on a regular page.
+     */
+    public static class RedirectResult extends SubmissionResult {
+
+        private final String target;
+
+        public RedirectResult(String target) {
+            this.target = target;
+        }
+
+        @Override
+        public boolean endsForm() {
+            return true;
+        }
+
+    }
+
+    /**
+     * The form has not finished and should be re-emitted, however no error
+     * occurred.
+     */
+    public static class FormContinue extends SubmissionResult {
+
+        @Override
+        public boolean endsForm() {
+            return false;
+        }
+    }
+
+    /**
+     * The form has successfully finished and a message should be emitted on a
+     * stateful page.
+     */
+    public static class SuccessMessageResult extends SubmissionResult {
+
+        private final Outputable message;
+
+        public SuccessMessageResult(Outputable message) {
+            this.message = message;
+        }
+
+        @Override
+        public boolean endsForm() {
+            return true;
+        }
+    }
+
     public static final String CSRF_FIELD = "csrf";
 
+    public static final String SUBMIT_RESULT = "form-submit-result";
+
     private final String csrf;
 
     private final String action;
@@ -52,40 +124,69 @@ public abstract class Form implements Outputable {
     /**
      * Update the forms internal state based on submitted data.
      * 
-     * @param out
-     *            the stream to the user.
      * @param req
      *            the request to take the initial data from.
      * @return true, iff the form succeeded and the user should be redirected.
      * @throws GigiApiException
-     *             if internal operations went wrong.
+     *             if form data had problems or operations went wrong.
      */
-    public abstract boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException;
+    public abstract SubmissionResult submit(HttpServletRequest req) throws GigiApiException;
+
+    public boolean submitExceptionProtected(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        try {
+            SubmissionResult res = submit(req);
+            req.setAttribute(SUBMIT_RESULT, res);
+            if (res instanceof RedirectResult) {
+                resp.sendRedirect(((RedirectResult) res).target);
+                return true;
+            }
+            if (res.endsForm()) {
+                HttpSession hs = req.getSession();
+                hs.removeAttribute("form/" + getClass().getName() + "/" + csrf);
+            }
+            return false;
+        } catch (PermamentFormException e) {
+            req.setAttribute(SUBMIT_RESULT, e);
+            return false;
+        } catch (GigiApiException e) {
+            req.setAttribute(SUBMIT_RESULT, e);
+            return false;
+        }
+    }
 
     /**
-     * Calls {@link #submit(PrintWriter, HttpServletRequest)} while catching and
-     * displaying errors ({@link GigiApiException}), and re-outputing the form
-     * via {@link #output(PrintWriter, Language, Map)}.
+     * Prints any errors in any form submits on this request.
      * 
-     * @param out
-     *            the target to write the form and errors to
      * @param req
-     *            the request that this submit originated (for submit and for
-     *            language)
-     * @return as {@link #submit(PrintWriter, HttpServletRequest)}: true, iff
-     *         the form succeeded and the user should be redirected.
+     *            The request to extract the errors from.
+     * @param out
+     *            the output stream to the user to write the errors to.
+     * @return true if no permanent errors occurred and the form should be
+     *         reprinted (and it has not already been successfully submitted)
      */
-    public boolean submitProtected(PrintWriter out, HttpServletRequest req) {
-        try {
-            boolean succeeded = submit(out, req);
-            if (succeeded) {
-                return true;
+    public static boolean printFormErrors(HttpServletRequest req, PrintWriter out) {
+        Object o = req.getAttribute(SUBMIT_RESULT);
+        if (o != null && (o instanceof PermamentFormException)) {
+            ((PermamentFormException) o).getCause().format(out, Page.getLanguage(req));
+            return false;
+        }
+        if (o != null && (o instanceof GigiApiException)) {
+            ((GigiApiException) o).format(out, Page.getLanguage(req));
+            return true;
+        }
+        if (o != null && (o instanceof FormContinue)) {
+            return true;
+        }
+        if (o != null && (o instanceof SuccessMessageResult)) {
+            Outputable message = ((SuccessMessageResult) o).message;
+            if (message != null) {
+                out.println("<div class='alert alert-success'>");
+                message.output(out, Page.getLanguage(req), new HashMap<String, Object>());
+                out.println("</div>");
             }
-        } catch (GigiApiException e) {
-            e.format(out, LoginPage.getLanguage(req));
+            return false;
         }
-        output(out, LoginPage.getLanguage(req), new HashMap<String, Object>());
-        return false;
+        return true;
     }
 
     protected String getCsrfFieldName() {
index 1c002e57a00959da796c408c91e0838381448747..69b05887bb0babd9d381603504031e8cccb55d2e 100644 (file)
@@ -39,12 +39,12 @@ public class LoginPage extends Page {
         }
 
         @Override
-        public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+        public RedirectResult submit(HttpServletRequest req) throws GigiApiException {
             if (RegisterPage.RATE_LIMIT.isLimitExceeded(req.getRemoteAddr())) {
                 throw new RateLimitException();
             }
             tryAuthWithUnpw(req);
-            return false;
+            return new RedirectResult(redirectPath(req));
         }
 
         @Override
@@ -56,18 +56,12 @@ public class LoginPage extends Page {
 
     public static final String LOGIN_RETURNPATH = "login-returnpath";
 
-    private static final String SUBMIT_EXCEPTION = "login-submit-exception";
-
     public LoginPage() {
         super("Password Login");
     }
 
     @Override
     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        Object o = req.getAttribute(SUBMIT_EXCEPTION);
-        if (o != null) {
-            ((GigiApiException) o).format(resp.getWriter(), getLanguage(req));
-        }
         if (req.getHeader("Host").equals(ServerConstants.getSecureHostNamePort())) {
             resp.getWriter().println(getLanguage(req).getTranslation("Authentication with certificate failed. Try another certificate or use a password."));
         } else {
@@ -75,39 +69,45 @@ public class LoginPage extends Page {
         }
     }
 
+    @Override
+    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            Form.getForm(req, LoginForm.class).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+        }
+    }
+
     @Override
     public boolean beforeTemplate(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        String redir = (String) req.getSession().getAttribute(LOGIN_RETURNPATH);
         if (req.getSession().getAttribute("loggedin") == null) {
             X509Certificate cert = getCertificateFromRequest(req);
             if (cert != null) {
                 tryAuthWithCertificate(req, cert);
             }
             if (req.getMethod().equals("POST")) {
-                try {
-                    Form.getForm(req, LoginForm.class).submit(resp.getWriter(), req);
-                } catch (GigiApiException e) {
-                    req.setAttribute(SUBMIT_EXCEPTION, e);
-                    return false;
-                }
+                return Form.getForm(req, LoginForm.class).submitExceptionProtected(req, resp);
             }
         }
 
         if (req.getSession().getAttribute("loggedin") != null) {
-            String s = redir;
-            if (s != null) {
-                if ( !s.startsWith("/")) {
-                    s = "/" + s;
-                }
-                resp.sendRedirect(s);
-            } else {
-                resp.sendRedirect("/");
-            }
+            resp.sendRedirect(redirectPath(req));
             return true;
         }
         return false;
     }
 
+    private static String redirectPath(HttpServletRequest req) {
+        String redir = (String) req.getSession().getAttribute(LOGIN_RETURNPATH);
+        String s = redir;
+        if (s != null) {
+            if ( !s.startsWith("/")) {
+                s = "/" + s;
+            }
+            return s;
+        } else {
+            return "/";
+        }
+    }
+
     @Override
     public boolean needsLogin() {
         return false;
@@ -164,11 +164,11 @@ public class LoginPage extends Page {
     }
 
     public static String extractSerialFormCert(X509Certificate x509Certificate) {
-        return x509Certificate.getSerialNumber().toString(16).toUpperCase();
+        return x509Certificate.getSerialNumber().toString(16).toLowerCase();
     }
 
     public static User fetchUserBySerial(String serial) {
-        if ( !serial.matches("[A-Fa-f0-9]+")) {
+        if ( !serial.matches("[a-f0-9]+")) {
             throw new Error("serial malformed.");
         }
 
diff --git a/src/org/cacert/gigi/pages/ManagedFormPage.java b/src/org/cacert/gigi/pages/ManagedFormPage.java
new file mode 100644 (file)
index 0000000..eabc902
--- /dev/null
@@ -0,0 +1,33 @@
+package org.cacert.gigi.pages;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.cacert.gigi.output.template.Form;
+
+public abstract class ManagedFormPage extends Page {
+
+    Class<? extends Form> c;
+
+    public ManagedFormPage(String title, Class<? extends Form> t) {
+        super(title);
+        c = t;
+    }
+
+    @Override
+    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            Form form = Form.getForm(req, c);
+            form.output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+        }
+    }
+
+    @Override
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        return Form.getForm(req, c).submitExceptionProtected(req, resp);
+    }
+
+}
diff --git a/src/org/cacert/gigi/pages/ManagedMultiFormPage.java b/src/org/cacert/gigi/pages/ManagedMultiFormPage.java
new file mode 100644 (file)
index 0000000..938a7f7
--- /dev/null
@@ -0,0 +1,32 @@
+package org.cacert.gigi.pages;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.cacert.gigi.output.template.Form;
+import org.cacert.gigi.output.template.Form.CSRFException;
+
+public abstract class ManagedMultiFormPage extends Page {
+
+    public ManagedMultiFormPage(String title) {
+        super(title);
+    }
+
+    @Override
+    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            getForm(req).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+        }
+    }
+
+    @Override
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        return getForm(req).submitExceptionProtected(req, resp);
+    }
+
+    public abstract Form getForm(HttpServletRequest req) throws CSRFException;
+
+}
index cfcc1983167675cffe15ff5a53218426e0c31ce8..512dad49367aeb126453531ad791f57b350c38df 100644 (file)
@@ -9,7 +9,7 @@ import javax.servlet.http.HttpServletResponse;
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.output.template.Form;
 
-public abstract class OneFormPage extends Page {
+public class OneFormPage extends Page {
 
     Class<? extends Form> c;
 
@@ -18,11 +18,16 @@ public abstract class OneFormPage extends Page {
         c = t;
     }
 
+    @Override
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        return Form.getForm(req, c).submitExceptionProtected(req, resp);
+    }
+
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         Form form = Form.getForm(req, c);
-        if (form.submitProtected(resp.getWriter(), req)) {
-            resp.sendRedirect(getSuccessPath(form));
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            form.output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
         }
     }
 
@@ -35,6 +40,4 @@ public abstract class OneFormPage extends Page {
         }
     }
 
-    public abstract String getSuccessPath(Form f);
-
 }
index 8d64d94f93cb884bfd7a94836c18debea283ee36..054a1e52020bf1172a095ea26a82ce5c3b4595dd 100644 (file)
@@ -58,6 +58,29 @@ public abstract class Page implements PermissionCheckable {
      *             if output goes wrong.
      */
     public boolean beforeTemplate(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        if (req.getMethod().equals("POST")) {
+            return beforePost(req, resp);
+        }
+        return false;
+    }
+
+    /**
+     * This method can be overridden to execute code and do stuff before the
+     * default template is applied when the request is a post request and the
+     * default implementation of
+     * {@link #beforeTemplate(HttpServletRequest, HttpServletResponse)} is
+     * called.
+     * 
+     * @param req
+     *            the request to handle.
+     * @param resp
+     *            the response to write to
+     * @return true, if the request is consumed and the default template should
+     *         not be applied.
+     * @throws IOException
+     *             if output goes wrong.
+     */
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         return false;
     }
 
index 4090bdd49b140822e7d516a879acdf0c6f9df9e1..580d0e54235da0c4e0305200f853fd1800ba86be 100644 (file)
@@ -16,8 +16,8 @@ import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.MailTemplate;
 import org.cacert.gigi.output.template.Template;
+import org.cacert.gigi.output.template.TranslateCommand;
 import org.cacert.gigi.util.AuthorizationContext;
-import org.cacert.gigi.util.HTMLEncoder;
 import org.cacert.gigi.util.RandomToken;
 import org.cacert.gigi.util.ServerConstants;
 
@@ -59,7 +59,7 @@ public class PasswordResetPage extends Page {
         }
 
         @Override
-        public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+        public SuccessMessageResult submit(HttpServletRequest req) throws GigiApiException {
             try (GigiPreparedStatement passwordReset = new GigiPreparedStatement("UPDATE `passwordResetTickets` SET `used` = CURRENT_TIMESTAMP WHERE `used` IS NULL AND `created` < CURRENT_TIMESTAMP - interval '1 hours' * ?;")) {
                 passwordReset.setInt(1, HOUR_MAX);
                 passwordReset.execute();
@@ -75,26 +75,26 @@ public class PasswordResetPage extends Page {
                 throw new GigiApiException("New passwords differ.");
             }
             u.consumePasswordResetTicket(id, tok, p1);
-            return true;
+            return new SuccessMessageResult(new TranslateCommand("Password reset successful."));
         }
 
         @Override
         protected void outputContent(PrintWriter out, Language l, Map<String, Object> vars) {
-
             t.output(out, l, vars);
         }
 
     }
 
+    @Override
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        return Form.getForm(req, PasswordResetForm.class).submitExceptionProtected(req, resp);
+    }
+
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        PasswordResetForm form = Form.getForm(req, PasswordResetForm.class);
-        PrintWriter w = resp.getWriter();
-        if (form.submitProtected(w, req)) {
-            w.println("<div class='alert alert-success'>");
-            w.println(HTMLEncoder.encodeHTML(getLanguage(req).getTranslation("Password reset successful.")));
-            w.println("</div>");
-            return;
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            PasswordResetForm form = Form.getForm(req, PasswordResetForm.class);
+            form.output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
         }
     }
 
@@ -114,7 +114,7 @@ public class PasswordResetPage extends Page {
 
     private static final MailTemplate passwordResetMail = new MailTemplate(PasswordResetPage.class.getResource("PasswordResetMail.templ"));
 
-    public static void initPasswordResetProcess(PrintWriter out, User targetUser, HttpServletRequest req, String aword, Language l, String method, String subject) {
+    public static void initPasswordResetProcess(User targetUser, HttpServletRequest req, String aword, Language l, String method, String subject) {
         String ptok = RandomToken.generateToken(32);
         int id = targetUser.generatePasswordResetTicket(Page.getUser(req), ptok, aword);
         try {
@@ -126,7 +126,6 @@ public class PasswordResetPage extends Page {
             vars.put("hour_max", HOUR_MAX);
 
             passwordResetMail.sendMail(l, vars, Page.getUser(req).getEmail());
-            out.println(Page.getLanguage(req).getTranslation("Password reset successful."));
         } catch (IOException e) {
             e.printStackTrace();
         }
index 2a5950e91e23e586329cec5446f3f0707bcca228..d7e5aed6bfe405c22512822755ab108da412c759 100644 (file)
@@ -15,6 +15,7 @@ import org.cacert.gigi.dbObjects.EmailAddress;
 import org.cacert.gigi.dbObjects.Verifyable;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.template.Form;
+import org.cacert.gigi.output.template.Scope;
 import org.cacert.gigi.output.template.SprintfCommand;
 
 public class Verify extends Page {
@@ -48,33 +49,32 @@ public class Verify extends Page {
                 Domain domain = Domain.getById(Integer.parseInt(id));
                 subject = domain.getSuffix();
                 target = domain;
+            } else {
+                throw new IllegalArgumentException();
             }
         }
 
         @Override
-        public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+        public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
             HashMap<String, Object> data = new HashMap<>();
             data.put("subject", subject);
             if ("email".equals(type)) {
                 try {
                     target.verify(hash);
-                    emailAddressVerified.output(out, getLanguage(req), data);
                 } catch (IllegalArgumentException e) {
-                    out.println(translate(req, "The email address is invalid."));
-                } catch (GigiApiException e) {
-                    e.format(out, getLanguage(req));
+                    throw new GigiApiException("The email address is invalid.");
                 }
+                return new SuccessMessageResult(new Scope(emailAddressVerified, data));
             } else if ("domain".equals(type)) {
                 try {
                     target.verify(hash);
-                    domainVerified.output(out, getLanguage(req), data);
                 } catch (IllegalArgumentException e) {
-                    out.println(translate(req, "The domain is invalid."));
-                } catch (GigiApiException e) {
-                    e.format(out, getLanguage(req));
+                    throw new GigiApiException("The domain is invalid.");
                 }
+                return new SuccessMessageResult(new Scope(domainVerified, data));
+            } else {
+                throw new GigiApiException("Invalid object type.");
             }
-            return true;
         }
 
         @Override
@@ -99,9 +99,15 @@ public class Verify extends Page {
         return false;
     }
 
+    @Override
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        return Form.getForm(req, VerificationForm.class).submitExceptionProtected(req, resp);
+    }
+
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        if (Form.getForm(req, VerificationForm.class).submitProtected(resp.getWriter(), req)) {
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            Form.getForm(req, VerificationForm.class).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
         }
     }
 
@@ -111,7 +117,6 @@ public class Verify extends Page {
             new VerificationForm(req).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
         } catch (IllegalArgumentException e) {
             resp.getWriter().println(translate(req, "The object to verify is invalid."));
-
         }
     }
 
index 667dc751fbc84a9e28637e410ba728e4e922a4b8..086c8a85c503aa350917eb5780f6780d484cee57 100644 (file)
@@ -10,7 +10,7 @@ import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.Template;
-import org.cacert.gigi.pages.Page;
+import org.cacert.gigi.output.template.TranslateCommand;
 
 public class ChangeForm extends Form {
 
@@ -29,18 +29,16 @@ public class ChangeForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         String oldpassword = req.getParameter("oldpassword");
         String p1 = req.getParameter("pword1");
         String p2 = req.getParameter("pword2");
         GigiApiException error = new GigiApiException();
         if (oldpassword == null || p1 == null || p2 == null) {
-            new GigiApiException("All fields are required.").format(out, Page.getLanguage(req));
-            return false;
+            throw new GigiApiException("All fields are required.");
         }
         if ( !p1.equals(p2)) {
-            new GigiApiException("New passwords do not match.").format(out, Page.getLanguage(req));
-            return false;
+            throw new GigiApiException("New passwords do not match.");
         }
         try {
             target.changePassword(oldpassword, p1);
@@ -48,10 +46,9 @@ public class ChangeForm extends Form {
             error.mergeInto(e);
         }
         if ( !error.isEmpty()) {
-            error.format(out, Page.getLanguage(req));
-            return false;
+            throw error;
         }
-        return true;
+        return new SuccessMessageResult(new TranslateCommand("Password changed."));
     }
 
 }
index 8432f027b0aaedc687d189a6605ab350ab34e65e..60cfaa0b33ceacd7735685ebad8aca9d690fa6d1 100644 (file)
@@ -7,16 +7,15 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.cacert.gigi.dbObjects.User;
-import org.cacert.gigi.output.template.Form;
-import org.cacert.gigi.pages.Page;
+import org.cacert.gigi.pages.ManagedFormPage;
 import org.cacert.gigi.util.AuthorizationContext;
 
-public class ChangePasswordPage extends Page {
+public class ChangePasswordPage extends ManagedFormPage {
 
     public static final String PATH = "/account/password";
 
     public ChangePasswordPage() {
-        super("Change Password");
+        super("Change Password", ChangeForm.class);
     }
 
     @Override
@@ -24,12 +23,6 @@ public class ChangePasswordPage extends Page {
         new ChangeForm(req, getUser(req)).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
     }
 
-    @Override
-    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        ChangeForm f = Form.getForm(req, ChangeForm.class);
-        f.submit(resp.getWriter(), req);
-    }
-
     @Override
     public boolean isPermitted(AuthorizationContext ac) {
         return ac != null && ac.getTarget() instanceof User;
index 98ee3ae35d0a6f156da8bc8577ac340c585e88c5..47735f3273cf3220da81c0963441c883ec12a878 100644 (file)
@@ -27,17 +27,17 @@ public class FindAgentAccess extends Form {
     private static final Template t = new Template(ChangePasswordPage.class.getResource("FindAgentAccess.templ"));
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         String nv = req.getParameter("new-val");
         if (nv == null) {
-            return false;
+            throw new GigiApiException("Parameter new-val missing.");
         }
         if (nv.equals("enable")) {
             target.grantGroup(target, Group.LOCATE_AGENT);
         } else {
             target.revokeGroup(target, Group.LOCATE_AGENT);
         }
-        return true;
+        return new RedirectResult(FindAgentAccess.PATH);
     }
 
     @Override
index bf80d47beaf53fb1197a5f169944342ab04fbe44..e6ba3ead537408fa6f1e36a0abfe480f01e4884a 100644 (file)
@@ -32,23 +32,25 @@ public class MyDetails extends Page {
     }
 
     @Override
-    public boolean beforeTemplate(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         if (req.getParameter("orgaForm") != null) {
-            Form.getForm(req, MyOrganisationsForm.class).submit(resp.getWriter(), req);
-        } else {
-            return false;
+            return Form.getForm(req, MyOrganisationsForm.class).submitExceptionProtected(req, resp);
         }
-        resp.sendRedirect(PATH);
-        return true;
+        if (req.getParameter("action") != null || req.getParameter("removeName") != null || req.getParameter("deprecateName") != null || req.getParameter("preferred") != null) {
+            return Form.getForm(req, MyDetailsForm.class).submitExceptionProtected(req, resp);
+        }
+        return false;
     }
 
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        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);
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            if (req.getParameter("orgaForm") != null) {
+                Form.getForm(req, MyOrganisationsForm.class).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+            }
+            if (req.getParameter("action") != null || req.getParameter("removeName") != null || req.getParameter("deprecateName") != null || req.getParameter("preferred") != null) {
+                Form.getForm(req, MyDetailsForm.class).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
             }
         }
-        super.doPost(req, resp);
     }
 }
index 813902289e623f925e5b89c2d9dad7ef10123169..f5b6f514fc6c3c9eca77816f5ab00a8b1d1eeefe 100644 (file)
@@ -19,7 +19,6 @@ import org.cacert.gigi.output.GroupSelector;
 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;
 
 public class MyDetailsForm extends Form {
 
@@ -56,7 +55,7 @@ public class MyDetailsForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         try {
             String rn = req.getParameter("removeName");
             if (rn != null) {
@@ -68,7 +67,7 @@ public class MyDetailsForm extends Form {
                     throw new GigiApiException("Cannot remove the account's preferred name.");
                 }
                 n.remove();
-                return true;
+                return new RedirectResult(MyDetails.PATH);
             }
             String dn = req.getParameter("deprecateName");
             if (dn != null) {
@@ -80,31 +79,29 @@ public class MyDetailsForm extends Form {
                     throw new GigiApiException("Cannot deprecate the account's preferred name.");
                 }
                 n.deprecate();
-                return true;
+                return new RedirectResult(MyDetails.PATH);
             }
             String pn = req.getParameter("preferred");
             if (pn != null) {
                 Name n = Name.getById(Integer.parseInt(pn));
                 target.setPreferredName(n);
-                return true;
+                return new RedirectResult(MyDetails.PATH);
             }
 
             String action = req.getParameter("action");
             if ("addName".equals(action)) {
                 ni.update(req);
                 ni.createName(target);
-                return true;
-            }
-            if ("updateDoB".equals(action)) {
+                return new RedirectResult(MyDetails.PATH);
+            } else if ("updateDoB".equals(action)) {
                 ds.update(req);
                 target.setDoB(ds.getDate());
-            }
-            if ("updateResidenceCountry".equals(action)) {
+                return new RedirectResult(MyDetails.PATH);
+            } else if ("updateResidenceCountry".equals(action)) {
                 cs.update(req);
                 target.setResidenceCountry(cs.getCountry());
-            }
-
-            if ("addGroup".equals(action) || "removeGroup".equals(action)) {
+                return new RedirectResult(MyDetails.PATH);
+            } else if ("addGroup".equals(action) || "removeGroup".equals(action)) {
                 selectedGroup.update(req);
                 Group toMod = selectedGroup.getGroup();
                 if ("addGroup".equals(action)) {
@@ -112,17 +109,14 @@ public class MyDetailsForm extends Form {
                 } else {
                     target.revokeGroup(target, toMod);
                 }
-                return true;
+                return new RedirectResult(MyDetails.PATH);
+            } else {
+                throw new GigiApiException("Invalid action.");
             }
 
-        } catch (GigiApiException e) {
-            e.format(out, Page.getLanguage(req));
-            return false;
         } catch (NumberFormatException e) {
-            new GigiApiException("Invalid value.").format(out, Page.getLanguage(req));
-            return false;
+            throw new GigiApiException("Invalid value.");
         }
-        return false;
     }
 
     @Override
index 706e95976d0b4222e4541cbef277d23228891af2..aaa84173e09cf8a78c283fb60199c0d521ae93ac 100644 (file)
@@ -9,6 +9,7 @@ import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
 
 import org.cacert.gigi.Gigi;
+import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.dbObjects.Organisation;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.template.Form;
@@ -29,10 +30,10 @@ public class MyOrganisationsForm extends Form {
     private static final Template template = new Template(MyOrganisationsForm.class.getResource("MyOrganisationsForm.templ"));
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         if (req.getParameter("org-leave") != null) {
             req.getSession().setAttribute(Gigi.AUTH_CONTEXT, new AuthorizationContext(target.getActor(), target.getActor()));
-            return true;
+            return new RedirectResult(MyDetails.PATH);
         }
         Enumeration<String> i = req.getParameterNames();
         int orgId = -1;
@@ -43,8 +44,7 @@ public class MyOrganisationsForm extends Form {
                 if (orgId == -1) {
                     orgId = id;
                 } else {
-                    out.println(LoginPage.getLanguage(req).getTranslation("Error: invalid parameter."));
-                    return false;
+                    throw new GigiApiException("Error: invalid parameter.");
                 }
             }
         }
@@ -52,11 +52,10 @@ public class MyOrganisationsForm extends Form {
             if (org.getId() == orgId) {
 
                 req.getSession().setAttribute(Gigi.AUTH_CONTEXT, new AuthorizationContext(org, target.getActor()));
-                return true;
+                return new RedirectResult(MyDetails.PATH);
             }
         }
-        System.out.println("Switch fialed");
-        return false;
+        throw new PermamentFormException(new GigiApiException("Context switch failed."));
     }
 
     @Override
index e37b930cd040a835e7baca178f4d490c4115c7f7..b61ec3ec62eaca1fc070a8513c2a5c509de3b7b2 100644 (file)
@@ -1,25 +1,21 @@
 package org.cacert.gigi.pages.account.certs;
 
 import java.io.IOException;
-import java.util.Collections;
 import java.util.HashMap;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.cacert.gigi.dbObjects.Certificate;
-import org.cacert.gigi.dbObjects.Certificate.CertificateStatus;
 import org.cacert.gigi.dbObjects.Group;
-import org.cacert.gigi.output.template.Form;
-import org.cacert.gigi.pages.Page;
+import org.cacert.gigi.pages.ManagedFormPage;
 import org.cacert.gigi.util.AuthorizationContext;
 
-public class CertificateAdd extends Page {
+public class CertificateAdd extends ManagedFormPage {
 
     public static final String PATH = "/account/certs/new";
 
     public CertificateAdd() {
-        super("Create certificate");
+        super("Create certificate", CertificateIssueForm.class);
     }
 
     @Override
@@ -27,26 +23,6 @@ public class CertificateAdd extends Page {
         new CertificateIssueForm(req).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
     }
 
-    @Override
-    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        CertificateIssueForm f = Form.getForm(req, CertificateIssueForm.class);
-        if (f.submit(resp.getWriter(), req)) {
-            Certificate c = f.getResult();
-            if (c.getStatus() != CertificateStatus.ISSUED) {
-                resp.getWriter().println("Timeout while waiting for certificate.");
-                return;
-            }
-            String ser = c.getSerial();
-            if (ser.isEmpty()) {
-                resp.getWriter().println("Timeout while waiting for certificate.");
-                return;
-            }
-            resp.sendRedirect(Certificates.PATH + "/" + ser);
-        }
-        f.output(resp.getWriter(), getLanguage(req), Collections.<String, Object>emptyMap());
-
-    }
-
     @Override
     public boolean isPermitted(AuthorizationContext ac) {
         return super.isPermitted(ac) && !ac.isInGroup(Group.BLOCKEDCERT);
index c4bca81dee1fe9f092f2dadbfd7b8fcad74e623f..da3bef21a1099a0aa32fa03e2a02870f3c037063 100644 (file)
         <a href='<?=$serial?>.crt'><?=_PEM encoded Certificate?></a>
         <? foreach($trustchain) { ?>
             <?=_issued by?> <a href='<?=$link?>'><?=$name?></a>
-        <? } ?><br/>
+        <? } ?>*<br/>
         <a href='<?=$serial?>.crt?chain'><?=_PEM encoded Certificate Chain?></a><br/>
         <a href='<?=$serial?>.crt?chain&noAnchor'><?=_PEM encoded Certificate Chain (Excluding Anchor)?></a><br/>
         <a href='<?=$serial?>.crt?chain&noLeaf'><?=_PEM encoded Certificate Chain (Excluding Leaf)?></a><br/>
         <a href='<?=$serial?>.cer'><?=_DER encoded Certificate?></a><br/>
         <a href='<?=$serial?>.cer?install&chain'><?=_Install into browser.?></a><br/>
-        <a href='<?=$serial?>.cer?install'><?=_Install into browser. (Chrome)?></a>. <?=_Please ensure that the intermediate certificates listed above are installed prior to installing the certificate.?><br/>
+        <a href='<?=$serial?>.cer?install'><?=_Install into browser (Chrome)?></a>. <?=_Please ensure that the intermediate certificates listed above are installed prior to installing the certificate.?>*<br/><br/>
+        * <?=_For information on how to install the root certificates into the truststore of your browser take a look at the !'<a href="https://wiki.cacert.org/FAQ/CSR">'FAQ!'</a>'!?>
+        
     </td>
   </tr>
 <? } ?>
index 0a95497d17935bc00b72a9428795daeb49b4dcc1..8b9272cc887610ec4bb60d786481010bc28484cc 100644 (file)
@@ -10,9 +10,12 @@ import javax.servlet.http.HttpServletRequest;
 
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.dbObjects.Certificate;
+import org.cacert.gigi.dbObjects.Certificate.CertificateStatus;
 import org.cacert.gigi.dbObjects.Certificate.SubjectAlternateName;
 import org.cacert.gigi.dbObjects.CertificateProfile;
+import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.Organisation;
+import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.CertificateValiditySelector;
 import org.cacert.gigi.output.HashAlgorithms;
@@ -20,7 +23,6 @@ import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.IterableDataset;
 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.RandomToken;
 
@@ -57,61 +59,66 @@ public class CertificateIssueForm extends Form {
     CertificateValiditySelector issueDate = new CertificateValiditySelector();
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         String csr = req.getParameter("CSR");
         String spkac = req.getParameter("SPKAC");
         try {
-            try {
-                if (csr != null) {
-                    cr = new CertificateRequest(c, csr);
-                    cr.checkKeyStrength(out);
-                } else if (spkac != null) {
-                    cr = new CertificateRequest(c, spkac, spkacChallenge);
-                    cr.checkKeyStrength(out);
-                } else if (cr != null) {
-                    login = "1".equals(req.getParameter("login"));
-                    issueDate.update(req);
-                    GigiApiException error = new GigiApiException();
-
-                    try {
-                        cr.update(req.getParameter("CN"), req.getParameter("hash_alg"), req.getParameter("profile"), //
-                                req.getParameter("org"), req.getParameter("OU"), req.getParameter("SANs"));
-                    } catch (GigiApiException e) {
-                        error.mergeInto(e);
-                    }
+            if (csr != null) {
+                cr = new CertificateRequest(c, csr);
+                // TODO cr.checkKeyStrength(out);
+                return new FormContinue();
+            } else if (spkac != null) {
+                cr = new CertificateRequest(c, spkac, spkacChallenge);
+                // TODO cr.checkKeyStrength(out);
+                return new FormContinue();
+            } else if (cr != null) {
+                login = "1".equals(req.getParameter("login"));
+                issueDate.update(req);
+                GigiApiException error = new GigiApiException();
+
+                try {
+                    cr.update(req.getParameter("CN"), req.getParameter("hash_alg"), req.getParameter("profile"), //
+                            req.getParameter("org"), req.getParameter("OU"), req.getParameter("SANs"));
+                } catch (GigiApiException e) {
+                    error.mergeInto(e);
+                }
 
-                    Certificate result = null;
-                    try {
-                        result = cr.draft();
-                    } catch (GigiApiException e) {
-                        error.mergeInto(e);
-                    }
-                    if ( !error.isEmpty() || result == null) {
-                        error.format(out, Page.getLanguage(req));
-                        return false;
-                    }
-                    if (login) {
-                        result.setLoginEnabled(true);
-                    }
-                    result.issue(issueDate.getFrom(), issueDate.getTo(), c.getActor()).waitFor(60000);
-                    this.result = result;
-                    return true;
-                } else {
-                    throw new GigiApiException("Error no action.");
+                Certificate result = null;
+                try {
+                    result = cr.draft();
+                } catch (GigiApiException e) {
+                    error.mergeInto(e);
                 }
-            } catch (IOException e) {
-                e.printStackTrace();
-            } catch (IllegalArgumentException e) {
-                e.printStackTrace();
-                throw new GigiApiException("Certificate Request format is invalid.");
-            } catch (GeneralSecurityException e) {
-                e.printStackTrace();
-                throw new GigiApiException("Certificate Request format is invalid.");
+                if ( !error.isEmpty() || result == null) {
+                    throw error;
+                }
+                if (login) {
+                    result.setLoginEnabled(true);
+                }
+                result.issue(issueDate.getFrom(), issueDate.getTo(), c.getActor()).waitFor(60000);
+                this.result = result;
+                Certificate c = result;
+                if (c.getStatus() != CertificateStatus.ISSUED) {
+                    throw new PermamentFormException(new GigiApiException("Timeout while waiting for certificate."));
+                }
+                String ser = c.getSerial();
+                if (ser.isEmpty()) {
+                    throw new PermamentFormException(new GigiApiException("Timeout while waiting for certificate."));
+                }
+                return new RedirectResult(Certificates.PATH + "/" + ser);
+            } else {
+                throw new GigiApiException("Error no action.");
             }
-        } catch (GigiApiException e) {
-            e.format(out, Page.getLanguage(req));
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new GigiApiException("Certificate Request format is invalid.");
+        } catch (IllegalArgumentException e) {
+            e.printStackTrace();
+            throw new GigiApiException("Certificate Request format is invalid.");
+        } catch (GeneralSecurityException e) {
+            e.printStackTrace();
+            throw new GigiApiException("Certificate Request format is invalid.");
         }
-        return false;
     }
 
     @Override
@@ -139,7 +146,16 @@ public class CertificateIssueForm extends Form {
             content.append(SAN.getName());
             content.append('\n');
         }
-
+        vars2.put("placeholderName", CertificateRequest.DEFAULT_CN);
+        if (c.getTarget() instanceof User) {
+            User target = (User) c.getTarget();
+            vars2.put("defaultName", target.getPreferredName().toString());
+            vars2.put("defaultEmail", target.getEmail());
+            Domain[] domains = target.getDomains();
+            if (domains.length > 0) {
+                vars2.put("defaultDomain", domains[0].getSuffix());
+            }
+        }
         vars2.put("CN", cr.getName());
         if (c.getTarget() instanceof Organisation) {
             vars2.put("orga", "true");
index e9947a970569f7b36c19bed74b1b5472537e566d..703bd98a5f3d16af6abf0a33c5a06790e9b4b35e 100644 (file)
@@ -1,10 +1,17 @@
-<h3><?=_CAcert Certificate Acceptable Use Policy?></h3>
-<p><?=_I hereby represent that I am fully authorized by the owner of the information contained in the CSR sent to SomeCA Inc. to apply for an Digital Certificate for secure and authenticated electronic transactions. I understand that a digital certificate serves to identify the Subscriber for the purposes of electronic communication and that the management of the private keys associated with such certificates is the responsibility of the subscriber's technical staff and/or contractors.?></p>
+<h3><?=_SomeCA Acceptable Use Policy?></h3>
+<p><?=_I hereby represent that I am fully authorized by the owner of the information contained in the CSR sent to SomeCA to apply for an Digital Certificate for secure and authenticated electronic transactions. I understand that a digital certificate serves to identify the Subscriber for the purposes of electronic communication and that the management of the private keys associated with such certificates is the responsibility of the subscriber's technical staff and/or contractors.?></p>
 
 <p><?=_CAcert Inc.'s public certification services are governed by a CPS as amended from time to time which is incorporated into this Agreement by reference. The Subscriber will use the SSL Server Certificate in accordance with SomeCA Inc.'s CPS and supporting documentation published at?> <a href="http://www.cacert.org/cps.php">http://www.cacert.org/cps.php</a></p>
 
 <p><?=_If the Subscriber's name and/or domain name registration change the subscriber will immediately inform SomeCA Inc. who shall revoke the digital certificate. When the Digital Certificate expires or is revoked the company will permanently remove the certificate from the server on which it is installed and will not use it for any purpose thereafter. The person responsible for key management and security is fully authorized to install and utilize the certificate to represent this organization's electronic presence.?></p>
-
+<span id="placeholderName" class="js-hint"><?=$placeholderName?></span>
+<? if($defaultName) { ?>
+<span id="defaultName" class="js-hint"><?=$defaultName?></span>
+<span id="defaultEmail" class="js-hint"><?=$defaultEmail?></span>
+<? } ?>
+<? if($defaultDomain) { ?>
+<span id="defaultDomain" class="js-hint"><?=$defaultDomain?></span>
+<? } ?>
 <table class="table">
   <thead>
   <tr>
   <tbody>
   <tr>
     <td>
-    <label for='profile'><?=_Key type?></label>
+      <label for='profile'><?=_Key type?></label>
     </td>
     <td>
-    <select name="profile" id='profile'>
+      <select name="profile" id='profile'>
     <? foreach($profiles) { ?>
-      <option value="<?=$key?>"<?=$!selected?>><?=$name?></option>
+        <option value="<?=$key?>"<?=$!selected?>><?=$name?></option>
     <? } ?>
-    </select>
+      </select>
+      <br />
+      <?=_Select desired type. To have your name added to a certificate you need to get your name verified with at least 50 !'<a href="/wot/rules" target="blank">'Verification Points (VP)!'</a>'.?>
     </td>
   </tr>
   <tr>
     <td>
-    <label for='CN'><?=_Your name?></label>
+      <label for='CN'><?=_Your name?></label>
+    </td>
+    <td>
+      <input class="form-control" type='text' id='CN' name='CN' value='<?=$CN?>'/>
+      <?=_For a client certificate you need to enter a name with at least 50 VP or 'SomeCA user' will be used.?><br />
+      <?=_For a server certificate leave this field blank.?>
     </td>
-    <td><input class="form-control" type='text' id='CN' name='CN' value='<?=$CN?>'/></td>
   </tr>
   <tr>
-    <td>SANs</td>
-    <td align="left"><textarea class="form-control" rows='5' name='SANs' placeholder="dns:my.domain.example.com, dns:*.example.com, email:my.email@example.com (or newline separated)"><?=$emails?></textarea></td>
+    <td>
+      <label for='SANs'>SANs</label>
+    </td>
+    <td align="left">
+      <textarea class="form-control" rows='5' name='SANs' placeholder="dns:my.domain.example.com, dns:*.example.com, email:my.email@example.com (or newline separated)"><?=$emails?></textarea><br />
+      <?=_Syntax for SAN?>: dns:my.domain.example.com, dns:*.example.com, email:my.email@example.com <?=_(or newline separated)?><br />
+      <?=_Recommendation for inexperienced users: only use one email address for client certificates.?>
+      </td>
   </tr>
   <? if($orga) { ?>
   <tr>
@@ -71,8 +90,9 @@
       <input type="checkbox" id="login" name="login" value="1" checked="checked" />
     </td>
     <td align="left">
-      <label for="login"><?=_Enable certificate login with this certificate?><br />
-      <?=_By allowing certificate login, this certificate can be used to log into this account at !'<code>https://secure.cacert.org/</code>'.?></label>
+      <label for="login"><?=_Enable certificate login with this certificate?></label><br />
+      <span><?=_By allowing certificate login, this certificate can be used to log into this account at !'<code>https://secure.cacert.org/</code>'.?><br />
+      <?=_Recommendation: Have at least one client certificate for login enabled.?></span>
     </td>
   </tr>
   <tr>
   </tr>
 
   <tr>
-    <td colspan="2"><input class="btn btn-primary" type="submit" name="process" value="<?=_Issue Certificate?>" /></td>
+    <td colspan="2">
+      <input class="btn btn-primary" type="submit" name="process" value="<?=_Issue Certificate?>" />  
+      <?=_Once the request is submitted, please be patient until the certificate is signed.?>
+    </td>
   </tr>
   </tbody>
 </table>
index fc36792091f27ce0f451937d206f5ec17d5d4085..7c3f7840689ea24c9c2c9136896a9a6d19b1d287 100644 (file)
@@ -6,6 +6,7 @@ import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
 
+import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.dbObjects.Certificate;
 import org.cacert.gigi.dbObjects.CertificateOwner;
 import org.cacert.gigi.dbObjects.Job;
@@ -32,15 +33,14 @@ public class CertificateModificationForm extends Form {
     private static final Template myTemplate = new Template(CertificateModificationForm.class.getResource("CertificateModificationForm.templ"));
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         String action = req.getParameter("action");
         if ( !"revoke".equals(action)) {
-            return false;
+            throw new GigiApiException("Incorrect action given.");
         }
         String[] certs = req.getParameterValues("certs[]");
         if (certs == null) {
-            // nothing to do
-            return false;
+            throw new GigiApiException("No certificates to revoke.");
         }
         LinkedList<Job> revokes = new LinkedList<Job>();
         for (String serial : certs) {
@@ -59,8 +59,7 @@ public class CertificateModificationForm extends Form {
                 break; // canceled... waited too log
             }
         }
-
-        return false;
+        return new RedirectResult(req.getPathInfo());
     }
 
     @Override
index 4db201cc38fcf4b1be4381283514a84b977dcd1c..23cd915da26b0a7b4dd5daf297af9afbbd526688 100644 (file)
@@ -49,6 +49,9 @@ public class Certificates extends Page implements HandlesMixedRequest {
 
     @Override
     public boolean beforeTemplate(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        if ("POST".equals(req.getMethod())) {
+            return beforePost(req, resp);
+        }
 
         String pi = req.getPathInfo().substring(PATH.length());
         if (pi.length() == 0) {
@@ -98,24 +101,35 @@ public class Certificates extends Page implements HandlesMixedRequest {
         return true;
     }
 
+    @Override
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        if (support && "revoke".equals(req.getParameter("action"))) {
+            return Form.getForm(req, RevokeSingleCertForm.class).submitExceptionProtected(req, resp);
+        }
+        if ( !req.getPathInfo().equals(PATH)) {
+            resp.sendError(500);
+            return true;
+        }
+        return Form.getForm(req, CertificateModificationForm.class).submitExceptionProtected(req, resp);
+    }
+
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         if (req.getQueryString() != null && !req.getQueryString().equals("") && !req.getQueryString().equals("withRevoked")) {
             return;// Block actions by get parameters.
         }
+
         if (support && "revoke".equals(req.getParameter("action"))) {
-            if (Form.getForm(req, RevokeSingleCertForm.class).submitProtected(resp.getWriter(), req)) {
-                resp.sendRedirect(req.getPathInfo());
-                return;
+            if (Form.printFormErrors(req, resp.getWriter())) {
+                Form.getForm(req, RevokeSingleCertForm.class).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
             }
+            return;
         }
         if ( !req.getPathInfo().equals(PATH)) {
             resp.sendError(500);
             return;
         }
-        Form.getForm(req, CertificateModificationForm.class).submit(resp.getWriter(), req);
-
-        doGet(req, resp);
+        Form.getForm(req, CertificateModificationForm.class).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
     }
 
     @Override
index 9ffd5da646ffaf179e69a9165aa9277a33439c61..32d327c2ded1ca2ba63cac4e961d7e3e1c48ec81 100644 (file)
@@ -1,3 +1,6 @@
+<p><?=_SomeCA offers two ways to create a certificate.?> 
+<?=_One is to paste a certificate signing request (CSR) created from an existing or newly created private key.?> <?=_ If you do not know what a CSR is or how to create one take a look at the !'<a href="https://someca.de/FAQ/CSR">'FAQ'!</a>'.?> 
+<?=_As an alternative you can generate the private key inside your browser and export it once the certificate has been issued.?></p>
 <form method="post">
 <table class="table">
   <thead>
@@ -7,9 +10,9 @@
   </thead>
   <tbody>
   <tr>
-    <td><?=_I have a CSR! Paste it here:?><br/><?=_Don't know what a CSR is or how to create one? Take a look at the !'<a href="https://wiki.cacert.org/FAQ/CSR">'Wiki!'</a>'!?></td>
+    <td><?=_I have some existing public key (SPKI) or signing request (CSR) I want to sign. Paste it here:?></td>
     <td>
-      <textarea class="form-control" name="CSR" class="csr"></textarea>
+      <textarea class="form-control" name="CSR" class="csr" rows="10" cols="80"></textarea>
     </td>
   </tr>
   <tr>
   </tbody>
 </table>
 </form>
-<br>
 <form method="post">
 <table class="table">
   <thead>
   <tr>
-    <th colspan="2" class="title"><?=_New Certificate from newly generatey Key (SPKAC)?></th>
+    <th colspan="2" class="title"><?=_Create a fresh key in the browser (SPKAC)?></th>
   </tr>
   </thead>
   <tbody>
   <tr>
     <td><?=_I do not have a CSR.?></td>
     <td align="left">
-     <keygen name="SPKAC" challenge="<?=$spkacChallenge?>"/>
+      <?=_key size (2048 recommended)?>: <keygen name="SPKAC" challenge="<?=$spkacChallenge?>"/>
     </td>
   </tr>
   <tr>
index 5219081aded3b03641448bd39497b8dd9ee2c3ed..372b5568e5f5bad691d0116f4a51de88baf25a29 100644 (file)
@@ -27,13 +27,13 @@ public class RevokeSingleCertForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public RedirectResult submit(HttpServletRequest req) throws GigiApiException {
         if (target != null) {
             target.revokeCertificate(c);
         } else {
             c.revoke().waitFor(60000);
         }
-        return true;
+        return new RedirectResult(req.getPathInfo());
     }
 
     @Override
index a0e5685bb109a13b7c2943280441843ecb326b72..584821796f6496b6e657d4a33a573421ba9e7aba 100644 (file)
@@ -12,7 +12,6 @@ import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.Outputable;
 import org.cacert.gigi.output.template.Template;
-import org.cacert.gigi.pages.Page;
 
 public class DomainAddForm extends Form {
 
@@ -29,7 +28,7 @@ public class DomainAddForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         try {
             String parameter = req.getParameter("newdomain");
             if (parameter.trim().isEmpty()) {
@@ -37,14 +36,10 @@ public class DomainAddForm extends Form {
             }
             Domain d = new Domain(target, target, parameter);
             pcf.setTarget(d);
-            pcf.submit(out, req);
-            return true;
+            pcf.submit(req);
+            return new RedirectResult(DomainOverview.PATH);
         } catch (NumberFormatException e) {
-            new GigiApiException("A number could not be parsed").format(out, Page.getLanguage(req));
-            return false;
-        } catch (GigiApiException e) {
-            e.format(out, Page.getLanguage(req));
-            return false;
+            throw new GigiApiException("A number could not be parsed");
         }
     }
 
index 568c8a3ad42521ccc8f3e81573ce2128dc3c6ae3..c6ea009f1d3dc669c8edfcfc8ed3fca1e9060bca 100644 (file)
@@ -12,6 +12,7 @@ import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.IterableDataset;
 import org.cacert.gigi.output.template.Template;
+import org.cacert.gigi.pages.orga.ViewOrgPage;
 
 public class DomainManagementForm extends Form {
 
@@ -28,7 +29,7 @@ public class DomainManagementForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         String dels = req.getParameter("delete");
 
         int delId = Integer.parseInt(dels);
@@ -38,11 +39,11 @@ public class DomainManagementForm extends Form {
         } else {
             throw new GigiApiException("Domain was not found.");
         }
-        return true;
-    }
-
-    public CertificateOwner getTarget() {
-        return target;
+        if (foreign) {
+            return new RedirectResult(ViewOrgPage.DEFAULT_PATH + "/" + target.getId());
+        } else {
+            return new RedirectResult(DomainOverview.PATH);
+        }
     }
 
     @Override
@@ -60,7 +61,7 @@ public class DomainManagementForm extends Form {
                 Domain domain = doms[point];
                 vars.put("id", domain.getId());
                 if ( !foreign) {
-                    vars.put("domainhref", DomainOverview.PATH + domain.getId());
+                    vars.put("domainhref", DomainOverview.PATH + "/" + domain.getId());
                 }
                 vars.put("domain", domain.getSuffix());
                 vars.put("status", l.getTranslation(domain.isVerified() ? "verified" : "not verified"));
index 97c47eeb43f41414f9fa442fc2fb6da7cb3cb056..aa2043a1fbd0765f867b12229279213577f86f8b 100644 (file)
@@ -8,15 +8,15 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.dbObjects.CertificateOwner;
-import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.output.template.Form;
+import org.cacert.gigi.output.template.Form.CSRFException;
 import org.cacert.gigi.pages.LoginPage;
-import org.cacert.gigi.pages.Page;
+import org.cacert.gigi.pages.ManagedMultiFormPage;
 
-public class DomainOverview extends Page {
+public class DomainOverview extends ManagedMultiFormPage {
 
-    public static final String PATH = "/account/domains/";
+    public static final String PATH = "/account/domains";
 
     public DomainOverview() {
         super("Domains");
@@ -25,29 +25,6 @@ public class DomainOverview extends Page {
     @Override
     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         CertificateOwner u = LoginPage.getAuthorizationContext(req).getTarget();
-        String pi = req.getPathInfo();
-        if (pi.length() - PATH.length() > 0) {
-            int i = Integer.parseInt(pi.substring(PATH.length()));
-            Domain d;
-            try {
-                d = Domain.getById(i);
-            } catch (IllegalArgumentException e) {
-                resp.getWriter().println(getLanguage(req).getTranslation("Access denied"));
-                return;
-            }
-            if (d == null || u.getId() != d.getOwner().getId()) {
-                resp.getWriter().println(getLanguage(req).getTranslation("Access denied"));
-                return;
-            }
-            new DomainPinglogForm(req, d).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
-            try {
-                new PingConfigForm(req, d).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
-            } catch (GigiApiException e) {
-                e.format(resp.getWriter(), getLanguage(req));
-            }
-            return;
-
-        }
         try {
             DomainManagementForm domMan = new DomainManagementForm(req, u, false);
             HashMap<String, Object> vars = new HashMap<>();
@@ -63,38 +40,12 @@ public class DomainOverview extends Page {
     }
 
     @Override
-    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        String pi = req.getPathInfo();
-        if (pi.length() - PATH.length() > 0) {
-            try {
-                if (req.getParameter("configId") != null) {
-                    if ( !Form.getForm(req, DomainPinglogForm.class).submit(resp.getWriter(), req)) {
-                        // error?
-                    }
-
-                } else {
-                    if ( !Form.getForm(req, PingConfigForm.class).submit(resp.getWriter(), req)) {
-
-                    }
-                }
-            } catch (GigiApiException e) {
-                e.format(resp.getWriter(), getLanguage(req));
-                return;
-            }
-
-            resp.sendRedirect(pi);
-        }
+    public Form getForm(HttpServletRequest req) throws CSRFException {
         if (req.getParameter("adddomain") != null) {
-            DomainAddForm f = Form.getForm(req, DomainAddForm.class);
-            if (f.submit(resp.getWriter(), req)) {
-                resp.sendRedirect(PATH);
-            }
+            return Form.getForm(req, DomainAddForm.class);
         } else if (req.getParameter("delete") != null) {
-            DomainManagementForm f = Form.getForm(req, DomainManagementForm.class);
-            if (f.submitProtected(resp.getWriter(), req)) {
-                resp.sendRedirect(PATH);
-            }
+            return Form.getForm(req, DomainManagementForm.class);
         }
-        super.doPost(req, resp);
+        return null;
     }
 }
index 525cd125c0ac5eef7c26d6a9f50b854fc20ac695..54209b20f34784894ee4b09e539d8daaa9b94e40 100644 (file)
@@ -28,21 +28,21 @@ public class DomainPinglogForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         CertificateOwner u = LoginPage.getAuthorizationContext(req).getTarget();
 
-        int i = Integer.parseInt(req.getPathInfo().substring(DomainOverview.PATH.length()));
+        int i = Integer.parseInt(req.getPathInfo().substring(DomainOverview.PATH.length() + 1));
         Domain d = Domain.getById(i);
         if (u.getId() != d.getOwner().getId()) {
-            return false;
+            throw new GigiApiException("Error, owner mismatch.");
         }
         int reping = Integer.parseInt(req.getParameter("configId"));
         DomainPingConfiguration dpc = DomainPingConfiguration.getById(reping);
         if (dpc.getTarget() != d) {
-            return false;
+            throw new GigiApiException("Error, target mismatch.");
         }
         dpc.requestReping();
-        return true;
+        return new RedirectResult(req.getPathInfo());
     }
 
     @Override
diff --git a/src/org/cacert/gigi/pages/account/domain/EditDomain.java b/src/org/cacert/gigi/pages/account/domain/EditDomain.java
new file mode 100644 (file)
index 0000000..f7df490
--- /dev/null
@@ -0,0 +1,67 @@
+package org.cacert.gigi.pages.account.domain;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.cacert.gigi.GigiApiException;
+import org.cacert.gigi.dbObjects.CertificateOwner;
+import org.cacert.gigi.dbObjects.Domain;
+import org.cacert.gigi.output.template.Form;
+import org.cacert.gigi.output.template.Form.CSRFException;
+import org.cacert.gigi.pages.LoginPage;
+import org.cacert.gigi.pages.ManagedMultiFormPage;
+
+public class EditDomain extends ManagedMultiFormPage {
+
+    public static final String PATH = "/account/domains/";
+
+    public EditDomain() {
+        super("Domain");
+    }
+
+    @Override
+    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        CertificateOwner u = LoginPage.getAuthorizationContext(req).getTarget();
+        String pi = req.getPathInfo();
+        if (pi.length() - PATH.length() <= 0) {
+            return;
+        }
+        Form.printFormErrors(req, resp.getWriter());
+        int i = Integer.parseInt(pi.substring(PATH.length()));
+        Domain d;
+        try {
+            d = Domain.getById(i);
+        } catch (IllegalArgumentException e) {
+            resp.getWriter().println(getLanguage(req).getTranslation("Access denied"));
+            return;
+        }
+        if (d == null || u.getId() != d.getOwner().getId()) {
+            resp.getWriter().println(getLanguage(req).getTranslation("Access denied"));
+            return;
+        }
+        new DomainPinglogForm(req, d).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+        try {
+            new PingConfigForm(req, d).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+        } catch (GigiApiException e) {
+            e.format(resp.getWriter(), getLanguage(req));
+        }
+
+    }
+
+    @Override
+    public Form getForm(HttpServletRequest req) throws CSRFException {
+        String pi = req.getPathInfo();
+        if (pi.length() - PATH.length() <= 0) {
+            return null;
+        }
+        if (req.getParameter("configId") != null) {
+            return Form.getForm(req, DomainPinglogForm.class);
+        } else {
+            return Form.getForm(req, PingConfigForm.class);
+        }
+    }
+
+}
index 496bc4cfb213b9b0ba70e05749af68acd7ff9be4..6d23c3a0a14ea4fbe0732cf9069bfc3cb2bece3d 100644 (file)
@@ -108,7 +108,7 @@ public class PingConfigForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         target.clearPings();
         if (req.getParameter("emailType") != null && req.getParameter("email") != null) {
             try {
@@ -142,7 +142,7 @@ public class PingConfigForm extends Form {
             }
         }
         Gigi.notifyPinger(null);
-        return false;
+        return new RedirectResult(req.getPathInfo());
     }
 
     @Override
index 1a67f8e23214cf137a906d571bc0dbe6ebec61d7..47cd8384e831ba7899a9b8b82a553f96afc1b1fe 100644 (file)
@@ -28,7 +28,7 @@ public class MailAddForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         String formMail = req.getParameter("newemail");
         mail = formMail;
         try {
@@ -36,7 +36,7 @@ public class MailAddForm extends Form {
         } catch (IllegalArgumentException e) {
             throw new GigiApiException(new PlainOutputable("Invalid address."));
         }
-        return true;
+        return new RedirectResult(MailOverview.DEFAULT_PATH);
     }
 
     @Override
index 9a399884a94a502a70e0a0ec533bd83df55e58b1..87087b7484c2de0a48295fda323b645087f9914b 100644 (file)
@@ -27,7 +27,7 @@ public class MailManagementForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         try {
             String d;
             if ((d = req.getParameter("default")) != null) {
@@ -37,14 +37,10 @@ public class MailManagementForm extends Form {
             } else if ((d = req.getParameter("reping")) != null) {
                 EmailAddress.getById(Integer.parseInt(d)).requestReping(Page.getLanguage(req));
             }
-        } catch (GigiApiException e) {
-            e.format(out, Page.getLanguage(req));
-            return false;
+            return new RedirectResult(MailOverview.DEFAULT_PATH);
         } catch (IOException e1) {
-            new GigiApiException("Error while doing reping.").format(out, Page.getLanguage(req));
-            return false;
+            throw new GigiApiException("Error while doing reping.");
         }
-        return true;
     }
 
     @Override
index b828b7189d7e6fcc8b10bd966cce9cbf7023003f..ef98a091238c35bc1e76ae7e0687cbfcce2c65bf 100644 (file)
@@ -1,20 +1,20 @@
 package org.cacert.gigi.pages.account.mail;
 
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.util.HashMap;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.template.Form;
+import org.cacert.gigi.output.template.Form.CSRFException;
+import org.cacert.gigi.pages.ManagedMultiFormPage;
 import org.cacert.gigi.pages.Page;
 import org.cacert.gigi.util.AuthorizationContext;
 
-public class MailOverview extends Page {
+public class MailOverview extends ManagedMultiFormPage {
 
     public static final String DEFAULT_PATH = "/account/mails";
 
@@ -24,37 +24,43 @@ public class MailOverview extends Page {
 
     @Override
     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        final User us = getUser(req);
+        User user = getUser(req);
+        output(req, resp, new MailAddForm(req, user), new MailManagementForm(req, user));
+    }
+
+    private void output(HttpServletRequest req, HttpServletResponse resp, MailAddForm addForm, MailManagementForm mgmtForm) throws IOException {
         Language lang = Page.getLanguage(req);
         HashMap<String, Object> vars = new HashMap<>();
-        vars.put("addForm", new MailAddForm(req, us));
-        vars.put("manForm", new MailManagementForm(req, us));
+        vars.put("addForm", addForm);
+        vars.put("manForm", mgmtForm);
         getDefaultTemplate().output(resp.getWriter(), lang, vars);
     }
 
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        PrintWriter out = resp.getWriter();
-        if (req.getParameter("addmail") != null) {
-            MailAddForm f = Form.getForm(req, MailAddForm.class);
-            try {
-                if (f.submit(out, req)) {
-                    resp.sendRedirect(MailOverview.DEFAULT_PATH);
-                }
-            } catch (GigiApiException e) {
-                e.format(resp.getWriter(), getLanguage(req));
+        Form current = getForm(req);
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            User user = getUser(req);
+            if (current instanceof MailAddForm) {
+                output(req, resp, (MailAddForm) current, new MailManagementForm(req, user));
+            } else {
+                output(req, resp, new MailAddForm(req, user), (MailManagementForm) current);
             }
+        }
+    }
+
+    @Override
+    public Form getForm(HttpServletRequest req) throws CSRFException {
+        if (req.getParameter("addmail") != null) {
+            return Form.getForm(req, MailAddForm.class);
         } else {
-            MailManagementForm f = Form.getForm(req, MailManagementForm.class);
-            if (f.submit(out, req)) {
-                resp.sendRedirect(MailOverview.DEFAULT_PATH);
-            }
+            return Form.getForm(req, MailManagementForm.class);
         }
-        super.doPost(req, resp);
     }
 
     @Override
     public boolean isPermitted(AuthorizationContext ac) {
         return ac != null && ac.getTarget() instanceof User;
     }
+
 }
index ce6eecb3bc6249d7b2b4ba47f56ada7eff185b34..2f3ee8429c830cbcef2b2a7fe4f7d3ecc58e1b80 100644 (file)
@@ -27,11 +27,11 @@ public class TTPAdminForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         if (req.getParameter("deny") != null) {
             u.revokeGroup(ttpAdmin, TTPAdminPage.TTP_APPLICANT);
         }
-        return false;
+        return new RedirectResult(TTPAdminPage.PATH);
     }
 
     @Override
index bf773cb4b9ac1946bae5d38b1c319baac3d28bf4..286a08d5639b377fb650d301c27153985a1a9d93 100644 (file)
@@ -28,10 +28,15 @@ public class TTPAdminPage extends Page {
         super("TTP-Admin");
     }
 
+    @Override
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        return Form.getForm(req, TTPAdminForm.class).submitExceptionProtected(req, resp);
+    }
+
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        if (Form.getForm(req, TTPAdminForm.class).submitProtected(resp.getWriter(), req)) {
-            resp.sendRedirect(PATH);
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            Form.getForm(req, TTPAdminForm.class).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
         }
     }
 
index 07d9b929ddd143d378c626f023e9cd8a56521d70..207a2a8a6242c1e3ff1f85e30e5a1b0c89ffbaa5 100644 (file)
@@ -15,6 +15,20 @@ import org.cacert.gigi.output.template.Template;
 
 public class FindCertForm extends Form {
 
+    public static class FindResult extends SuccessMessageResult {
+
+        private final Certificate[] certs;
+
+        public FindResult(Certificate[] certs) {
+            super(null);
+            this.certs = certs;
+        }
+
+        public Certificate[] getCerts() {
+            return certs;
+        }
+    }
+
     private static final Template t = new Template(FindCertForm.class.getResource("FindCertForm.templ"));
 
     private final String SERIAL = "serial";
@@ -28,7 +42,7 @@ public class FindCertForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         this.certType = req.getParameter("certType");
         String request = req.getParameter("cert").trim();
 
@@ -50,7 +64,7 @@ public class FindCertForm extends Form {
                 throw new GigiApiException(SprintfCommand.createSimple("No certificate found matching {0}", request));
             }
         }
-        return true;
+        return new FindCertForm.FindResult(getCerts());
     }
 
     @Override
index 2e1f913471797551e9e9b3ffe4968683385b0fd2..e7f6b95e4a4a9558a45f0328f51a7de4394973c6 100644 (file)
@@ -33,11 +33,15 @@ public class FindCertPage extends Page {
         new FindCertForm(req).output(resp.getWriter(), Page.getLanguage(req), new HashMap<String, Object>());
     }
 
+    @Override
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        return Form.getForm(req, FindCertForm.class).submitExceptionProtected(req, resp);
+    }
+
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        FindCertForm form = Form.getForm(req, FindCertForm.class);
-        if (form.submitProtected(resp.getWriter(), req)) {
-            final Certificate[] certs = form.getCerts();
+        if ( !Form.printFormErrors(req, resp.getWriter())) {
+            final Certificate[] certs = ((FindCertForm.FindResult) req.getAttribute(Form.SUBMIT_RESULT)).getCerts();
             if (certs.length == 1) {
                 resp.sendRedirect(Certificates.SUPPORT_PATH + "/" + certs[0].getSerial());
             } else {
index cce4aa0d84929f1a041a51d76451ceec1485f3ae..9aae447036155ec8e4dd4e986b49f0db239591fe 100644 (file)
@@ -8,6 +8,8 @@ import javax.servlet.http.HttpServletRequest;
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.dbObjects.CertificateOwner;
 import org.cacert.gigi.dbObjects.Domain;
+import org.cacert.gigi.dbObjects.Organisation;
+import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.SprintfCommand;
@@ -15,6 +17,20 @@ import org.cacert.gigi.output.template.Template;
 
 public class FindUserByDomainForm extends Form {
 
+    public static class FindDomainResult extends SuccessMessageResult {
+
+        private final CertificateOwner owner;
+
+        public FindDomainResult(CertificateOwner owner) {
+            super(null);
+            this.owner = owner;
+        }
+
+        public CertificateOwner getOwner() {
+            return owner;
+        }
+    }
+
     private CertificateOwner res = null;
 
     private static final Template t = new Template(FindUserByDomainForm.class.getResource("FindUserByDomainForm.templ"));
@@ -24,7 +40,7 @@ public class FindUserByDomainForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         String request = req.getParameter("domain");
         Domain d = null;
         if (request.matches("#[0-9]+")) {
@@ -40,7 +56,13 @@ public class FindUserByDomainForm extends Form {
             throw new GigiApiException(SprintfCommand.createSimple("No personal domains found matching {0}", request));
         }
         res = d.getOwner();
-        return true;
+        if (res instanceof User) {
+            return new RedirectResult(SupportUserDetailsPage.PATH + res.getId() + "/");
+        } else if (res instanceof Organisation) {
+            return new RedirectResult("/support/domain/" + res.getId());
+        } else {
+            throw new PermamentFormException(new GigiApiException("Unknown owner type."));
+        }
     }
 
     @Override
index 3572d3e626460699d2d2ca4ef28189c81977cb1f..8a64218087c871c49de63299faffa9dab5c7d1c5 100644 (file)
@@ -1,13 +1,16 @@
 package org.cacert.gigi.pages.admin.support;
 
-import org.cacert.gigi.dbObjects.CertificateOwner;
-import org.cacert.gigi.dbObjects.Organisation;
-import org.cacert.gigi.dbObjects.User;
-import org.cacert.gigi.output.template.Form;
-import org.cacert.gigi.pages.OneFormPage;
+import java.io.IOException;
+import java.util.HashMap;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.cacert.gigi.pages.ManagedFormPage;
+import org.cacert.gigi.pages.Page;
 import org.cacert.gigi.util.AuthorizationContext;
 
-public class FindUserByDomainPage extends OneFormPage {
+public class FindUserByDomainPage extends ManagedFormPage {
 
     public static final String PATH = "/support/find/domain";
 
@@ -16,15 +19,8 @@ public class FindUserByDomainPage extends OneFormPage {
     }
 
     @Override
-    public String getSuccessPath(Form f) {
-        CertificateOwner res = ((FindUserByDomainForm) f).getRes();
-        if (res instanceof User) {
-            return SupportUserDetailsPage.PATH + res.getId() + "/";
-        } else if (res instanceof Organisation) {
-            return "/support/domain/" + res.getId();
-        } else {
-            throw new Error("Unknown owner type.");
-        }
+    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        new FindUserByDomainForm(req).output(resp.getWriter(), Page.getLanguage(req), new HashMap<String, Object>());
     }
 
     @Override
index 12c33e97d75fcac13c077ad47986439bc0ccc0a3..2978c48e213ce6435775713ea2c4bfad1ed7f0b4 100644 (file)
@@ -14,7 +14,19 @@ import org.cacert.gigi.output.template.Template;
 
 public class FindUserByEmailForm extends Form {
 
-    private EmailAddress emails[];
+    public static class FindEmailResult extends SuccessMessageResult {
+
+        private final EmailAddress[] emails;
+
+        public FindEmailResult(EmailAddress[] emails) {
+            super(null);
+            this.emails = emails;
+        }
+
+        public EmailAddress[] getEmails() {
+            return emails;
+        }
+    }
 
     private static final Template t = new Template(FindUserByDomainForm.class.getResource("FindUserByEmailForm.templ"));
 
@@ -23,22 +35,16 @@ public class FindUserByEmailForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         EmailAddress[] emails = EmailAddress.findByAllEmail(req.getParameter("email"));
         if (emails.length == 0) {
             throw new GigiApiException(SprintfCommand.createSimple("No users found matching {0}", req.getParameter("email")));
         }
-        this.emails = emails;
-        return true;
+        return new FindUserByEmailForm.FindEmailResult(emails);
     }
 
     @Override
     protected void outputContent(PrintWriter out, Language l, Map<String, Object> vars) {
         t.output(out, l, vars);
     }
-
-    public EmailAddress[] getEmails() {
-        return emails;
-    }
-
 }
index 15e6933e69a2d9a602f374bde77c2d1598f1402d..9d731712cb9df146018f48ba14c293ba0b8d23a3 100644 (file)
@@ -30,11 +30,17 @@ public class FindUserByEmailPage extends Page {
         new FindUserByEmailForm(req).output(resp.getWriter(), Page.getLanguage(req), new HashMap<String, Object>());
     }
 
+    @Override
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        return Form.getForm(req, FindUserByEmailForm.class).submitExceptionProtected(req, resp);
+    }
+
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        FindUserByEmailForm form = Form.getForm(req, FindUserByEmailForm.class);
-        if (form.submitProtected(resp.getWriter(), req)) {
-            final EmailAddress[] emails = form.getEmails();
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            Form.getForm(req, FindUserByEmailForm.class).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+        } else {
+            final EmailAddress[] emails = ((FindUserByEmailForm.FindEmailResult) req.getAttribute(Form.SUBMIT_RESULT)).getEmails();
             if (emails.length == 1) {
                 resp.sendRedirect(SupportUserDetailsPage.PATH + emails[0].getOwner().getId() + "/");
             } else {
index 18afc0c662279ccf76ca0fd503e57693220c4272..e2e30a93d153169fced9f5858167be37e48b0510 100644 (file)
@@ -22,22 +22,22 @@ public class SupportEnterTicketForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         if (req.getParameter("setTicket") != null) {
             // [asdmASDM]\d{8}\.\d+
             String ticket = req.getParameter("ticketno");
             if (ticket.matches("[asdmASDM]\\d{8}\\.\\d+")) {
                 AuthorizationContext ac = LoginPage.getAuthorizationContext(req);
                 req.getSession().setAttribute(Gigi.AUTH_CONTEXT, new AuthorizationContext(ac.getActor(), ticket));
-                return true;
+                return new RedirectResult(SupportEnterTicketPage.PATH);
             }
-            return false;
+            throw new GigiApiException("Ticket format malformed");
         } else if (req.getParameter("deleteTicket") != null) {
             AuthorizationContext ac = LoginPage.getAuthorizationContext(req);
             req.getSession().setAttribute(Gigi.AUTH_CONTEXT, new AuthorizationContext(ac.getActor(), ac.getActor()));
-            return true;
+            return new RedirectResult(SupportEnterTicketPage.PATH);
         }
-        return false;
+        throw new GigiApiException("No valid action given.");
     }
 
     @Override
index eb1cfcabf3d19a5ab8bddad35296592935491ed3..01cc695fbe7a79edb8da2a0d91cbd0d6d8ff01a9 100644 (file)
@@ -6,7 +6,6 @@ import java.util.HashMap;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.dbObjects.Group;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.pages.LoginPage;
@@ -22,20 +21,12 @@ public class SupportEnterTicketPage extends Page {
     }
 
     @Override
-    public boolean beforeTemplate(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         if (req.getParameter("setTicket") == null && req.getParameter("deleteTicket") == null) {
             return false;
         }
         SupportEnterTicketForm f = Form.getForm(req, SupportEnterTicketForm.class);
-        try {
-            if (f.submit(resp.getWriter(), req)) {
-                resp.sendRedirect(PATH);
-                return true;
-            }
-        } catch (GigiApiException e) {
-            e.format(resp.getWriter(), getLanguage(req));
-        }
-        return false;
+        return f.submitExceptionProtected(req, resp);
 
     }
 
@@ -46,6 +37,14 @@ public class SupportEnterTicketPage extends Page {
         new SupportEnterTicketForm(req).output(resp.getWriter(), getLanguage(req), vars);
     }
 
+    @Override
+    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            SupportEnterTicketForm f = Form.getForm(req, SupportEnterTicketForm.class);
+            f.output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+        }
+    }
+
     @Override
     public boolean isPermitted(AuthorizationContext ac) {
         return ac != null && ac.isInGroup(Group.SUPPORTER);
index 9c1f3f5be3ae726cd98cab710ac1be4dcd41695c..5b163cc46af10ab6f82a158102b01b605e0003c0 100644 (file)
@@ -30,12 +30,12 @@ public class SupportRevokeCertificatesForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
-        if (user.getTicket() != null) {
-            user.revokeAllCertificates();
-            return true;
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
+        if (user.getTicket() == null) {
+            throw new GigiApiException("No ticket number set.");
         }
-        return false;
+        user.revokeAllCertificates();
+        return new RedirectResult(req.getPathInfo());
     }
 
     @Override
index d3589c8e4ad6b9a187b681400f7251a6399c7634..88b9b03b583a8081ef360f087f3a4ce646dbad05 100644 (file)
@@ -18,6 +18,7 @@ import org.cacert.gigi.output.GroupIterator;
 import org.cacert.gigi.output.GroupSelector;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.Template;
+import org.cacert.gigi.output.template.TranslateCommand;
 import org.cacert.gigi.pages.LoginPage;
 
 public class SupportUserDetailsForm extends Form {
@@ -37,9 +38,9 @@ public class SupportUserDetailsForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         if (user.getTicket() == null) {
-            return false;
+            throw new GigiApiException("No ticket number set.");
         }
         if (user.getTargetUser() == LoginPage.getUser(req)) {
             throw new GigiApiException("Supporter may not modify himself.");
@@ -55,22 +56,22 @@ public class SupportUserDetailsForm extends Form {
             } else {
                 user.revoke(toMod);
             }
-            return true;
+            return new RedirectResult(req.getPathInfo());
         }
         if (req.getParameter("resetPass") != null) {
             String aword = req.getParameter("aword");
             if (aword == null || aword.equals("")) {
                 throw new GigiApiException("An A-Word is required to perform a password reset.");
             }
-            user.triggerPasswordReset(aword, out, req);
-            return true;
+            user.triggerPasswordReset(aword, req);
+            return new SuccessMessageResult(new TranslateCommand("Password reset successful."));
         }
         dobSelector.update(req);
         if ( !dobSelector.isValid()) {
             throw new GigiApiException("Invalid date of birth!");
         }
         user.setDob(dobSelector.getDate());
-        return true;
+        return new RedirectResult(req.getPathInfo());
     }
 
     @Override
index 04898f8ca20be6777c2ace5aff6dafcc6c66e15a..eea69f6dbfcbb9ebe0961157b4b8c78bf920356d 100644 (file)
@@ -7,19 +7,19 @@ import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.dbObjects.Domain;
 import org.cacert.gigi.dbObjects.EmailAddress;
 import org.cacert.gigi.dbObjects.SupportedUser;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.template.Form;
+import org.cacert.gigi.output.template.Form.CSRFException;
 import org.cacert.gigi.output.template.IterableDataset;
 import org.cacert.gigi.pages.LoginPage;
-import org.cacert.gigi.pages.Page;
+import org.cacert.gigi.pages.ManagedMultiFormPage;
 import org.cacert.gigi.util.AuthorizationContext;
 
-public class SupportUserDetailsPage extends Page {
+public class SupportUserDetailsPage extends ManagedMultiFormPage {
 
     public static final String PATH = "/support/user/";
 
@@ -29,19 +29,32 @@ public class SupportUserDetailsPage extends Page {
 
     @Override
     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        User user = getUser(req, resp);
+        if (user == null) {
+            return;
+        }
+        SupportedUser targetUser = new SupportedUser(user, getUser(req), LoginPage.getAuthorizationContext(req).getSupporterTicketId());
+        outputContents(req, resp, user, new SupportRevokeCertificatesForm(req, targetUser), new SupportUserDetailsForm(req, targetUser));
+    }
+
+    private User getUser(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         int id = -1;
         if ( !req.getPathInfo().endsWith("/")) {
             resp.sendError(404);
+            return null;
         }
         String[] idP = req.getPathInfo().split("/");
         try {
             id = Integer.parseInt(idP[idP.length - 1]);
         } catch (NumberFormatException e) {
             resp.sendError(404);
+            return null;
         }
         final User user = User.getById(id);
-        SupportedUser targetUser = new SupportedUser(user, getUser(req), LoginPage.getAuthorizationContext(req).getSupporterTicketId());
-        SupportUserDetailsForm f = new SupportUserDetailsForm(req, targetUser);
+        return user;
+    }
+
+    private void outputContents(HttpServletRequest req, HttpServletResponse resp, final User user, SupportRevokeCertificatesForm certificatesForm, SupportUserDetailsForm f) throws IOException {
         HashMap<String, Object> vars = new HashMap<String, Object>();
         vars.put("details", f);
         final EmailAddress[] addrs = user.getEmails();
@@ -82,31 +95,41 @@ public class SupportUserDetailsPage extends Page {
             }
         });
 
-        vars.put("certifrevoke", new SupportRevokeCertificatesForm(req, targetUser));
+        vars.put("certifrevoke", certificatesForm);
         getDefaultTemplate().output(resp.getWriter(), getLanguage(req), vars);
     }
 
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        try {
-            if (req.getParameter("revokeall") != null) {
-                if ( !Form.getForm(req, SupportRevokeCertificatesForm.class).submit(resp.getWriter(), req)) {
-                    throw new GigiApiException("No ticket number set.");
-                }
-            } else if (req.getParameter("detailupdate") != null || req.getParameter("resetPass") != null || req.getParameter("removeGroup") != null || req.getParameter("addGroup") != null) {
-                if ( !Form.getForm(req, SupportUserDetailsForm.class).submit(resp.getWriter(), req)) {
-                    throw new GigiApiException("No ticket number set.");
-                }
+        User user = getUser(req, resp);
+        if (user == null) {
+            return;
+        }
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            Form f = getForm(req);
+            SupportedUser targetUser = new SupportedUser(user, getUser(req), LoginPage.getAuthorizationContext(req).getSupporterTicketId());
+
+            if (f instanceof SupportUserDetailsForm) {
+                outputContents(req, resp, user, new SupportRevokeCertificatesForm(req, targetUser), (SupportUserDetailsForm) f);
+            } else if (f instanceof SupportRevokeCertificatesForm) {
+                outputContents(req, resp, user, (SupportRevokeCertificatesForm) f, new SupportUserDetailsForm(req, targetUser));
             }
-        } catch (GigiApiException e) {
-            e.printStackTrace();
-            e.format(resp.getWriter(), getLanguage(req));
         }
-        super.doPost(req, resp);
+
     }
 
     @Override
     public boolean isPermitted(AuthorizationContext ac) {
         return ac != null && ac.canSupport();
     }
+
+    @Override
+    public Form getForm(HttpServletRequest req) throws CSRFException {
+        if (req.getParameter("revokeall") != null) {
+            return Form.getForm(req, SupportRevokeCertificatesForm.class);
+        } else if (req.getParameter("detailupdate") != null || req.getParameter("resetPass") != null || req.getParameter("removeGroup") != null || req.getParameter("addGroup") != null) {
+            return Form.getForm(req, SupportUserDetailsForm.class);
+        }
+        return null;
+    }
 }
index 30c428333702991664e451aa3dc6b9b9452d32d7..69dc4c1085062d042484c4e60f4730496b5c13ef 100644 (file)
@@ -1,14 +1,11 @@
 package org.cacert.gigi.pages.main;
 
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.util.HashMap;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
 
-import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.pages.Page;
 import org.cacert.gigi.util.AuthorizationContext;
@@ -16,8 +13,6 @@ import org.cacert.gigi.util.RateLimit;
 
 public class RegisterPage extends Page {
 
-    private static final String SIGNUP_PROCESS = "signupProcess";
-
     public static final String PATH = "/register";
 
     // 50 per 5 min
@@ -34,27 +29,21 @@ public class RegisterPage extends Page {
     }
 
     private void outputGet(HttpServletRequest req, HttpServletResponse resp, Signup s) throws IOException {
-        PrintWriter out = resp.getWriter();
-        HashMap<String, Object> vars = new HashMap<String, Object>();
-        getDefaultTemplate().output(out, getLanguage(req), vars);
-        s.output(out, getLanguage(req), vars);
+        getDefaultTemplate().output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+        s.output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+    }
+
+    @Override
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        return Form.getForm(req, Signup.class).submitExceptionProtected(req, resp);
     }
 
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        Signup s = Form.getForm(req, Signup.class);
-        try {
-            if (s.submit(resp.getWriter(), req)) {
-                HttpSession hs = req.getSession();
-                hs.setAttribute(SIGNUP_PROCESS, null);
-                resp.getWriter().println(translate(req, "Your information has been submitted" + " into our system. You will now be sent an email with a web link," + " you need to open that link in your web browser within 24 hours" + " or your information will be removed from our system!"));
-                return;
-            }
-        } catch (GigiApiException e) {
-            e.format(resp.getWriter(), getLanguage(req));
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            Signup s = Form.getForm(req, Signup.class);
+            outputGet(req, resp, s);
         }
-
-        outputGet(req, resp, s);
     }
 
     @Override
index 819bfd5b08286215aa3ce144195f80c03378f7e7..011b63843d43aaee07d8c405f268236a5ad516ba 100644 (file)
@@ -20,6 +20,7 @@ import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.PlainOutputable;
 import org.cacert.gigi.output.template.SprintfCommand;
 import org.cacert.gigi.output.template.Template;
+import org.cacert.gigi.output.template.TranslateCommand;
 import org.cacert.gigi.pages.Page;
 import org.cacert.gigi.util.CalendarUtil;
 import org.cacert.gigi.util.HTMLEncoder;
@@ -93,7 +94,7 @@ public class Signup extends Form {
     }
 
     @Override
-    public synchronized boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public synchronized SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         if (RegisterPage.RATE_LIMIT.isLimitExceeded(req.getRemoteAddr())) {
             throw new RateLimitException();
         }
@@ -183,7 +184,7 @@ public class Signup extends Form {
             throw ga2;
         }
         run(req, pw1);
-        return true;
+        return new SuccessMessageResult(new TranslateCommand("Your information has been submitted" + " into our system. You will now be sent an email with a web link," + " you need to open that link in your web browser within 24 hours" + " or your information will be removed from our system!"));
     }
 
     private void run(HttpServletRequest req, String password) throws GigiApiException {
index cef4dc912e2c8d340483213227dd54caf3d1b0ad..42682fedcf949371ac1e83e5b7ca5bdae05eadc4 100644 (file)
@@ -16,7 +16,6 @@ import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.IterableDataset;
 import org.cacert.gigi.output.template.Template;
 import org.cacert.gigi.pages.LoginPage;
-import org.cacert.gigi.pages.Page;
 
 public class AffiliationForm extends Form {
 
@@ -30,24 +29,23 @@ public class AffiliationForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         if (req.getParameter("del") != null) {
             User toRemove = User.getByEmail(req.getParameter("del"));
             if (toRemove != null) {
                 o.removeAdmin(toRemove, LoginPage.getUser(req));
-                return true;
+                return new RedirectResult(ViewOrgPage.DEFAULT_PATH + "/" + o.getId());
             }
         } else if (req.getParameter("do_affiliate") != null) {
             User byEmail = User.getByEmail(req.getParameter("email"));
             if (byEmail != null && byEmail.canAssure()) {
                 o.addAdmin(byEmail, LoginPage.getUser(req), req.getParameter("master") != null);
-                return true;
+                return new RedirectResult(ViewOrgPage.DEFAULT_PATH + "/" + o.getId());
             } else {
-                out.println(Page.getLanguage(req).getTranslation("Requested user is not a RA Agent. We need a RA Agent here."));
+                throw new GigiApiException("Requested user is not a RA Agent. We need a RA Agent here.");
             }
         }
-        out.println(Page.getLanguage(req).getTranslation("No action could have been carried out."));
-        return false;
+        throw new GigiApiException("No action could have been carried out.");
     }
 
     @Override
@@ -71,8 +69,4 @@ public class AffiliationForm extends Form {
         });
         t.output(out, l, vars);
     }
-
-    public Organisation getOrganisation() {
-        return o;
-    }
 }
index 36bbbe8e511c23ac168891b886f79d6db376349f..4abcafa363c77e9b85c64d6f10222efb6ac8a9f4 100644 (file)
@@ -6,7 +6,6 @@ import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
 
 import org.cacert.gigi.GigiApiException;
-import org.cacert.gigi.dbObjects.Country;
 import org.cacert.gigi.dbObjects.Organisation;
 import org.cacert.gigi.email.EmailProvider;
 import org.cacert.gigi.localisation.Language;
@@ -59,10 +58,10 @@ public class CreateOrgForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         String action = req.getParameter("action");
         if (action == null) {
-            return false;
+            throw new GigiApiException("No action given.");
         }
 
         if (action.equals("new")) {
@@ -70,18 +69,16 @@ public class CreateOrgForm extends Form {
             checkOrganisationData(req);
             Organisation ne = new Organisation(o, cs.getCountry(), st, l, email, optionalName, postalAddress, LoginPage.getUser(req));
             result = ne;
-            return true;
         } else if (action.equals("updateOrganisationData")) {
             checkOrganisationData(req);
             result.updateOrgData(email, optionalName, postalAddress);
-            return true;
         } else if (action.equals("updateCertificateData")) {
             checkCertData(req);
             result.updateCertData(o, cs.getCountry(), st, l);
-            return true;
+        } else {
+            throw new GigiApiException("No valid action given.");
         }
-
-        return false;
+        return new RedirectResult(ViewOrgPage.DEFAULT_PATH + "/" + result.getId());
     }
 
     private void checkOrganisationData(HttpServletRequest req) throws GigiApiException {
@@ -121,10 +118,6 @@ public class CreateOrgForm extends Form {
         return parameter.trim();
     }
 
-    public Organisation getResult() {
-        return result;
-    }
-
     @Override
     protected void outputContent(PrintWriter out, Language l, Map<String, Object> vars) {
         vars.put("O", o);
index 249871f29f31ea57bba7c7f90afcabcdd12e00f4..17d2a318a519296adc73766ed5e4ab05f3e9d224 100644 (file)
@@ -7,18 +7,17 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.cacert.gigi.dbObjects.Group;
-import org.cacert.gigi.output.template.Form;
-import org.cacert.gigi.pages.Page;
+import org.cacert.gigi.pages.ManagedFormPage;
 import org.cacert.gigi.util.AuthorizationContext;
 
-public class CreateOrgPage extends Page {
+public class CreateOrgPage extends ManagedFormPage {
 
     public static final Group ORG_ASSURER = Group.ORGASSURER;
 
     public static final String DEFAULT_PATH = "/orga/new";
 
     public CreateOrgPage() {
-        super("Create Organisation");
+        super("Create Organisation", CreateOrgForm.class);
     }
 
     @Override
@@ -26,15 +25,6 @@ public class CreateOrgPage extends Page {
         return ac != null && ac.isInGroup(ORG_ASSURER);
     }
 
-    @Override
-    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        CreateOrgForm form = Form.getForm(req, CreateOrgForm.class);
-        if (form.submitProtected(resp.getWriter(), req)) {
-            resp.sendRedirect(ViewOrgPage.DEFAULT_PATH + "/" + form.getResult().getId());
-            return;
-        }
-    }
-
     @Override
     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         new CreateOrgForm(req).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
index c18cf8f11494cd7399accb31019596923c348dc7..78e04b405b46f94461af02717e9382f46f0f578f 100644 (file)
@@ -24,15 +24,11 @@ public class OrgDomainAddForm extends Form {
         this.target = target;
     }
 
-    public Organisation getOrganisation() {
-        return target;
-    }
-
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         String domain = req.getParameter("domain");
         new Domain(LoginPage.getUser(req), target, domain);
-        return true;
+        return new RedirectResult(ViewOrgPage.DEFAULT_PATH + "/" + target.getId());
     }
 
     @Override
index d1d1d51906a1df6e5fd0ce924a628199575f97f0..887761076759dd37df1fd5170f2cfa481172f7d8 100644 (file)
@@ -13,14 +13,15 @@ import org.cacert.gigi.dbObjects.Organisation;
 import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.template.Form;
+import org.cacert.gigi.output.template.Form.CSRFException;
 import org.cacert.gigi.output.template.IterableDataset;
 import org.cacert.gigi.output.template.Template;
 import org.cacert.gigi.pages.LoginPage;
-import org.cacert.gigi.pages.Page;
+import org.cacert.gigi.pages.ManagedMultiFormPage;
 import org.cacert.gigi.pages.account.domain.DomainManagementForm;
 import org.cacert.gigi.util.AuthorizationContext;
 
-public class ViewOrgPage extends Page {
+public class ViewOrgPage extends ManagedMultiFormPage {
 
     private static final Template orgas = new Template(ViewOrgPage.class.getResource("ViewOrgs.templ"));
 
@@ -38,38 +39,22 @@ public class ViewOrgPage extends Page {
     }
 
     @Override
-    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        User u = LoginPage.getUser(req);
+    public Form getForm(HttpServletRequest req) throws CSRFException {
         if (req.getParameter("do_affiliate") != null || req.getParameter("del") != null) {
-            AffiliationForm form = Form.getForm(req, AffiliationForm.class);
-            if (form.submitProtected(resp.getWriter(), req)) {
-                resp.sendRedirect(DEFAULT_PATH + "/" + form.getOrganisation().getId());
-            }
-            return;
+            return Form.getForm(req, AffiliationForm.class);
         } else {
-            if ( !u.isInGroup(CreateOrgPage.ORG_ASSURER)) {
-                resp.sendError(403, "Access denied");
-                return;
+            if ( !getUser(req).isInGroup(CreateOrgPage.ORG_ASSURER)) {
+                return null;
             }
 
             if (req.getParameter("addDomain") != null) {
-                OrgDomainAddForm form = Form.getForm(req, OrgDomainAddForm.class);
-                if (form.submitProtected(resp.getWriter(), req)) {
-                    resp.sendRedirect(DEFAULT_PATH + "/" + form.getOrganisation().getId());
-                }
+                return Form.getForm(req, OrgDomainAddForm.class);
             } else if (req.getParameter("delete") != null) {
-                DomainManagementForm form = Form.getForm(req, DomainManagementForm.class);
-                if (form.submitProtected(resp.getWriter(), req)) {
-                    resp.sendRedirect(DEFAULT_PATH + "/" + form.getTarget().getId());
-                }
+                return Form.getForm(req, DomainManagementForm.class);
             } else {
-                CreateOrgForm form = Form.getForm(req, CreateOrgForm.class);
-                if (form.submitProtected(resp.getWriter(), req)) {
-                    resp.sendRedirect(DEFAULT_PATH + "/" + form.getResult().getId());
-                }
+                return Form.getForm(req, CreateOrgForm.class);
             }
         }
-
     }
 
     @Override
index 8ad735fbd8b78e48f0c261a05d73c1fa0c235443..b46dfdd530637785a4fcb10b974f8b0459a34061 100644 (file)
@@ -20,8 +20,10 @@ import org.cacert.gigi.output.ArrayIterable;
 import org.cacert.gigi.output.CountrySelector;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.IterableDataset;
+import org.cacert.gigi.output.template.Outputable;
 import org.cacert.gigi.output.template.SprintfCommand;
 import org.cacert.gigi.output.template.Template;
+import org.cacert.gigi.output.template.TranslateCommand;
 import org.cacert.gigi.pages.Page;
 import org.cacert.gigi.pages.PasswordResetPage;
 import org.cacert.gigi.util.DayDate;
@@ -29,6 +31,25 @@ import org.cacert.gigi.util.Notary;
 
 public class AssuranceForm extends Form {
 
+    public static class ConcatOutputable implements Outputable {
+
+        private Outputable[] outputables;
+
+        public ConcatOutputable(Outputable... outputables) {
+            this.outputables = outputables;
+        }
+
+        @Override
+        public void output(PrintWriter out, Language l, Map<String, Object> vars) {
+            for (int i = 0; i < outputables.length; i++) {
+                if (i != 0) {
+                    out.println();
+                }
+                outputables[i].output(out, l, vars);
+            }
+        }
+    }
+
     private User assuree;
 
     private Name[] assureeNames;
@@ -134,7 +155,7 @@ public class AssuranceForm extends Form {
     }
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         location = req.getParameter("location");
         date = req.getParameter("date");
         cs.update(req);
@@ -195,14 +216,19 @@ public class AssuranceForm extends Form {
         }
 
         Notary.assureAll(assurer, assuree, dob, pointsI, location, req.getParameter("date"), type, toAssure.toArray(new Name[toAssure.size()]), cs.getCountry());
-
-        if (aword != null && !aword.equals("")) {
+        Outputable result = new TranslateCommand("Verification complete.");
+        if (isWithPasswordReset()) {
             Language langApplicant = Language.getInstance(assuree.getPreferredLocale());
             String method = langApplicant.getTranslation("A password reset was triggered. If you did a password reset by verification, please enter your secret password using this form:");
             String subject = langApplicant.getTranslation("Password reset by verification");
-            PasswordResetPage.initPasswordResetProcess(out, assuree, req, aword, langApplicant, method, subject);
+            PasswordResetPage.initPasswordResetProcess(assuree, req, aword, langApplicant, method, subject);
+            result = new ConcatOutputable(result, new TranslateCommand("Password reset successful."));
         }
-        return true;
+        return new SuccessMessageResult(result);
+    }
+
+    public boolean isWithPasswordReset() {
+        return aword != null && !aword.equals("");
     }
 
     public User getAssuree() {
index 95ab35f0bc223b3246d61325e0577f446864596c..8ce8f72b4dd7c1f1ab5262c113785a7ad9fc4847 100644 (file)
@@ -44,14 +44,22 @@ public class AssurePage extends Page {
         return ac != null && ac.canAssure();
     }
 
+    @Override
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        if (req.getParameter("search") == null) {
+            AssuranceForm form = Form.getForm(req, AssuranceForm.class);
+            return form.submitExceptionProtected(req, resp);
+        }
+        return super.beforePost(req, resp);
+    }
+
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
         PrintWriter out = resp.getWriter();
         if (req.getParameter("search") == null) {
-            AssuranceForm form = Form.getForm(req, AssuranceForm.class);
-            if (form.submitProtected(out, req)) {
-                out.println(translate(req, "Verification complete."));
-                return;
+            if (Form.printFormErrors(req, out)) {
+                AssuranceForm form = Form.getForm(req, AssuranceForm.class);
+                form.output(out, getLanguage(req), new HashMap<String, Object>());
             }
             return;
         }
index 3a6f7fe422c9e2ec885909c317e800e211140484..7348346fc30a35fc4831803d01a15e20f2e9867a 100644 (file)
@@ -12,6 +12,7 @@ import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.template.Form;
 import org.cacert.gigi.output.template.OutputableArrayIterable;
 import org.cacert.gigi.output.template.Template;
+import org.cacert.gigi.output.template.TranslateCommand;
 import org.cacert.gigi.pages.LoginPage;
 
 public class RequestTTPForm extends Form {
@@ -32,7 +33,7 @@ public class RequestTTPForm extends Form {
     };
 
     @Override
-    public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException {
+    public SubmissionResult submit(HttpServletRequest req) throws GigiApiException {
         String country = req.getParameter("country");
         if (country != null) {
             int cid = Integer.parseInt(country);
@@ -46,12 +47,11 @@ public class RequestTTPForm extends Form {
         User uReq = LoginPage.getUser(req);
 
         if ( !u.equals(uReq)) {
-            return false;
+            throw new GigiApiException("Internal logic error.");
         }
 
         u.grantGroup(u, TTP_APPLICANT);
-
-        return false;
+        return new SuccessMessageResult(new TranslateCommand("Successfully applied for TTP."));
     }
 
     @Override
index 7e50059d63172f58db35d536017e045ee8ae29ff..f4b739c462cadf6b6ef27caa042c62a1d6997409 100644 (file)
@@ -21,9 +21,16 @@ public class RequestTTPPage extends Page {
         super("Request TTP");
     }
 
+    @Override
+    public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+        return Form.getForm(req, RequestTTPForm.class).submitExceptionProtected(req, resp);
+    }
+
     @Override
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        Form.getForm(req, RequestTTPForm.class).submitProtected(resp.getWriter(), req);
+        if (Form.printFormErrors(req, resp.getWriter())) {
+            Form.getForm(req, RequestTTPForm.class).output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+        }
     }
 
     @Override
index b66e38c835809fbb1d09bcf54292edb2288dec36..a17fc09801bd903863f3d5e0791f39dc874e2844 100644 (file)
@@ -6,7 +6,7 @@ Subject: <?=_Verification entered by you?>
 <?=_You granted ${points} Verification Points to the following verified name(s):?>
 
 <? foreach($names) { ?>\
-<?=_${name}?>
+<?=$name?>
 <? } ?>\
 
 <?=_You meet the Applicant on ${date} at ${location}, ${country}.?>
index f8cd07292df2975ae34f499ffa3a918169f4739d..7bb2ee87b38c4caeb138b8ab1b6530548bd0218d 100644 (file)
@@ -23,3 +23,6 @@ div.error-msgs p{
 .summary-table td{
     padding: 0 3px;
 }
+.js-hint {
+    display: none;
+}
\ No newline at end of file
index 731dddde58f991e28868b2ec48e016fe4ab21384..9c623e7321ad95e530f496dd7bf739eef6a20fb4 100644 (file)
            }
          }
        }
+       function initCertForm() {
+               if(document.getElementById("placeholderName") == null) {
+                       return;
+               }
+               function getHint(id){
+                       var elem = document.getElementById(id);
+                       if(elem === null) {
+                               return null;
+                       }
+                       return $(elem).text();
+               }
+               $("select[name=profile]").off("change");
+               $("textarea[name=SANs]").off("keydown");
+               $("textarea[name=SANs]").get(0).modified=false;
+               $("input[name=CN]").off("keydown");
+               $("input[name=CN]").get(0).modified=false;
+
+               var placeholderName = getHint("placeholderName");
+               var defaultName = getHint("defaultName");
+               var defaultEmail = getHint("defaultEmail");
+               var defaultDomain = getHint("defaultDomain");
+               if(defaultName === null) {
+                       return;
+               }
+               $("textarea[name=SANs]").on("keydown", function(){
+                       this.modified = this.value !== "";
+               });
+               $("input[name=CN]").on("keydown", function(){
+                       this.modified = this.value !== "";
+               });
+
+               var loginCheck = document.getElementById("login");
+               $("select[name=profile]").change(function(){
+                       var val = this.value;
+                       var sans = $("textarea[name=SANs]").get(0);
+                       if(val.match(/client.*/)) {
+                               loginCheck.checked = true;
+                               loginCheck.disabled = false;
+                       } else {
+                               loginCheck.checked = false;
+                               loginCheck.disabled = true;
+                       }
+                       if(val.match(/client.*|mail.*/)) {
+                               if(!sans.modified) {
+                                       sans.value = "email:"+defaultEmail;
+                               }
+                       } else if(val.match(/server.*/)) {
+                               if(!sans.modified) {
+                                       sans.value = defaultDomain === null ? "" : "dns:" + defaultDomain;
+                               }
+                       }
+                       var cn = $("input[name=CN]").get(0);
+                       if(val.match(/.*-a/)) {
+                               if(!cn.modified) {
+                                       cn.value = defaultName;
+                               }
+                       }else{
+                               if(!cn.modified) {
+                                       cn.value = placeholderName;
+                               }
+                       }
+               });
+               var children = $("select[name=profile]").get(0).children;
+               var target = "client-mail";
+               for(var i=0; i < children.length; i++){
+                       if(children[i].value == "client-mail-a"){
+                               target = "client-mail-a";
+                       }
+               }
+
+               $("select[name=profile]").get(0).value = target;
+               $("select[name=profile]").trigger("change");
+
+       }
        function init(){
                showExpert(false);
+               initCertForm();
                var expert = document.getElementById("expertbox");
                if(expert !== null) {
                        expert.onchange = (function(expert){return function(){showExpert(expert.checked)}})(expert);
index 4d6529db3197554802749bfefeee3430c04db9aa..cbce25d49e17fa30e573b6b57582ed3df4432ea9 100644 (file)
@@ -378,9 +378,9 @@ public class TestCertificateAdd extends ClientTest {
     @Test
     public void testSetLoginEnabled() throws IOException, GeneralSecurityException {
         X509Certificate parsedLoginNotEnabled = createCertWithValidity("&validFrom=now&validity=1m", false);
-        assertNull(CertificateOwner.getByEnabledSerial(parsedLoginNotEnabled.getSerialNumber().toString(16)));
+        assertNull(CertificateOwner.getByEnabledSerial(parsedLoginNotEnabled.getSerialNumber().toString(16).toLowerCase()));
 
         X509Certificate parsedLoginEnabled = createCertWithValidity("&validFrom=now&validity=1m", true);
-        assertEquals(u, CertificateOwner.getByEnabledSerial(parsedLoginEnabled.getSerialNumber().toString(16)));
+        assertEquals(u, CertificateOwner.getByEnabledSerial(parsedLoginEnabled.getSerialNumber().toString(16).toLowerCase()));
     }
 }
index 01ee4c5980b869b56054abc0b647a639eb0ff5bd..0c7aced4cae714482f96eb11bca77c4f910bfaf7 100644 (file)
@@ -234,6 +234,9 @@ public class ManagedTest extends ConfiguredTest {
         uc.addRequestProperty("Cookie", headerField);
         uc.setDoOutput(true);
         uc.getOutputStream().write((param + "&csrf=" + csrf).getBytes("UTF-8"));
+        if (uc.getResponseCode() == 302) {
+            return "";
+        }
         String d = IOUtils.readURL(uc);
         return d;
     }
@@ -346,6 +349,9 @@ public class ManagedTest extends ConfiguredTest {
         if (headerField == null) {
             return "";
         }
+        if (huc.getResponseCode() != 302) {
+            fail(fetchStartErrorMessage(IOUtils.readURL(huc)));
+        }
         return stripCookie(headerField);
     }
 
@@ -437,7 +443,10 @@ public class ManagedTest extends ConfiguredTest {
     }
 
     public static String executeBasicWebInteraction(String cookie, String path, String query, int formIndex) throws IOException, MalformedURLException, UnsupportedEncodingException {
-        URLConnection uc = post(cookie, path, query, formIndex);
+        HttpURLConnection uc = post(cookie, path, query, formIndex);
+        if (uc.getResponseCode() == 302) {
+            return null;
+        }
         String error = fetchStartErrorMessage(IOUtils.readURL(uc));
         return error;
     }
index 967fdb2ded062a95e998f640767bd77ecbee4cfc..55c5683ac46a965ceda4f473586261bfb90e604b 100644 (file)
@@ -53,16 +53,16 @@ public abstract class PingTest extends ClientTest {
         openConnection.getHeaderField("Location");
         int code = ((HttpURLConnection) openConnection).getResponseCode();
         if (code != 302) {
-            throw new Error("Code was: " + code + "\ncontent was: " + IOUtils.readURL(openConnection));
+            throw new Error("Code was: " + code + "\ncontent was: " + fetchStartErrorMessage(IOUtils.readURL(openConnection)));
         }
 
         String newcontent = IOUtils.readURL(get(DomainOverview.PATH));
-        Pattern dlink = Pattern.compile(DomainOverview.PATH + "([0-9]+)'>");
+        Pattern dlink = Pattern.compile(DomainOverview.PATH + "/([0-9]+)'>");
         Matcher m1 = dlink.matcher(newcontent);
         if ( !m1.find()) {
             throw new Error(newcontent);
         }
-        return DomainOverview.PATH + m1.group(1);
+        return DomainOverview.PATH + "/" + m1.group(1);
     }
 
     protected Matcher initailizeDomainForm() throws IOException, Error {
index 21b2452567f30552d3bb9055f8f795b11f36201f..30694f09566d372dcb3279074936f04d45d2cee0 100644 (file)
@@ -17,3 +17,5 @@ org.cacert.gigi.output.template TranslateCommand.TranslateCommand(String),0=>org
 org.cacert.gigi.pages.account.domain DomainOverview.DomainOverview(String),0
 org.cacert.gigi.dbObjects Group.Group(String, String, boolean, boolean, boolean),1
 org.cacert.gigi.output.template SprintfCommand.createSimple(String, Object[]),0
+org.cacert.gigi.pages ManagedFormPage.ManagedFormPage(String, Class),0
+org.cacert.gigi.pages ManagedMultiFormPage.ManagedMultiFormPage(String),0
index 9a2fb1074f612bd62ce4f5f850d31ec644b87fd8..f2b97d7bcd958380088ebf432372f2e9eef36a62 100644 (file)
@@ -127,14 +127,14 @@ public class SimpleSigner {
                     readyCerts = new GigiPreparedStatement("SELECT certs.id AS id, certs.csr_name, jobs.id AS jobid, csr_type, md, `executeFrom`, `executeTo`, profile FROM jobs " + //
                             "INNER JOIN certs ON certs.id=jobs.`targetId` " + //
                             "INNER JOIN profiles ON profiles.id=certs.profile " + //
-                            "WHERE jobs.state='open' "//
-                            "AND task='sign'");
+                            "WHERE jobs.state='open' " + //
+                            "AND task='sign'");
 
                     getSANSs = new GigiPreparedStatement("SELECT contents, type FROM `subjectAlternativeNames` " + //
                             "WHERE `certId`=?");
 
                     updateMail = new GigiPreparedStatement("UPDATE certs SET crt_name=?," + " created=NOW(), serial=?, caid=? WHERE id=?");
-                    warnMail = new GigiPreparedStatement("UPDATE jobs SET warning=warning+1, state=IF(warning<3, 'open','error') WHERE id=?");
+                    warnMail = new GigiPreparedStatement("UPDATE jobs SET warning=warning+1, state=CASE WHEN warning<3 THEN 'open'::`jobState` ELSE 'error'::`jobState` END WHERE id=?");
 
                     revoke = new GigiPreparedStatement("SELECT certs.id, certs.csr_name,jobs.id FROM jobs INNER JOIN certs ON jobs.`targetId`=certs.id" + " WHERE jobs.state='open' AND task='revoke'");
                     revokeCompleted = new GigiPreparedStatement("UPDATE certs SET revoked=NOW() WHERE id=?");
@@ -335,10 +335,13 @@ public class SimpleSigner {
                 if (null == caFiles) {
                     caFiles = new File[0];
                 }
-                for (File f : caFiles) {
-                    if (f.getName().startsWith(caP.getProperty("ca"))) {
-                        ca = f.getName();
-                        break;
+                if ( !new File(parent, ca).exists()) {
+                    System.out.println("CA " + ca + " not found. Searching for anything other remotely fitting.");
+                    for (File f : caFiles) {
+                        if (f.getName().startsWith(caP.getProperty("ca"))) {
+                            ca = f.getName();
+                            break;
+                        }
                     }
                 }
                 File caKey = new File(parent, ca + "/ca.key");
@@ -511,6 +514,7 @@ public class SimpleSigner {
 
         try (DerOutputStream dos = new DerOutputStream()) {
             for (String name : eku.split(",")) {
+                name = name.trim();
                 ObjectIdentifier oid;
                 switch (name) {
                 case "serverAuth":