From: Felix Dörre Date: Wed, 14 Sep 2016 19:45:01 +0000 (+0200) Subject: Merge "upd: native Makefile improvements" X-Git-Url: https://code.wpia.club/?p=gigi.git;a=commitdiff_plain;h=bdb770e853028d8510a941c936a290ab69cf675c;hp=5ea2f92d90210c2f6254b216aa4863635d3ae645 Merge "upd: native Makefile improvements" --- diff --git a/debian/gigi-standalone.service b/debian/gigi-standalone.service index e60e2eed..776625f8 100644 --- a/debian/gigi-standalone.service +++ b/debian/gigi-standalone.service @@ -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 diff --git a/src/org/cacert/gigi/Gigi.java b/src/org/cacert/gigi/Gigi.java index afe6bcb7..23f10df9 100644 --- a/src/org/cacert/gigi/Gigi.java +++ b/src/org/cacert/gigi/Gigi.java @@ -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"); diff --git a/src/org/cacert/gigi/api/CATSResolve.java b/src/org/cacert/gigi/api/CATSResolve.java index 1b25e9d5..0e9f2a01 100644 --- a/src/org/cacert/gigi/api/CATSResolve.java +++ b/src/org/cacert/gigi/api/CATSResolve.java @@ -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; diff --git a/src/org/cacert/gigi/dbObjects/CertificateOwner.java b/src/org/cacert/gigi/dbObjects/CertificateOwner.java index cc96ade7..ab854bcc 100644 --- a/src/org/cacert/gigi/dbObjects/CertificateOwner.java +++ b/src/org/cacert/gigi/dbObjects/CertificateOwner.java @@ -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)); diff --git a/src/org/cacert/gigi/dbObjects/SupportedUser.java b/src/org/cacert/gigi/dbObjects/SupportedUser.java index 67b5e119..e600b85b 100644 --- a/src/org/cacert/gigi/dbObjects/SupportedUser.java +++ b/src/org/cacert/gigi/dbObjects/SupportedUser.java @@ -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); } diff --git a/src/org/cacert/gigi/output/template/Form.java b/src/org/cacert/gigi/output/template/Form.java index 1eb0efa0..82d9e600 100644 --- a/src/org/cacert/gigi/output/template/Form.java +++ b/src/org/cacert/gigi/output/template/Form.java @@ -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("
"); + message.output(out, Page.getLanguage(req), new HashMap()); + out.println("
"); } - } catch (GigiApiException e) { - e.format(out, LoginPage.getLanguage(req)); + return false; } - output(out, LoginPage.getLanguage(req), new HashMap()); - return false; + return true; } protected String getCsrfFieldName() { diff --git a/src/org/cacert/gigi/pages/LoginPage.java b/src/org/cacert/gigi/pages/LoginPage.java index 1c002e57..69b05887 100644 --- a/src/org/cacert/gigi/pages/LoginPage.java +++ b/src/org/cacert/gigi/pages/LoginPage.java @@ -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()); + } + } + @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 index 00000000..eabc9027 --- /dev/null +++ b/src/org/cacert/gigi/pages/ManagedFormPage.java @@ -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 c; + + public ManagedFormPage(String title, Class 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()); + } + } + + @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 index 00000000..938a7f75 --- /dev/null +++ b/src/org/cacert/gigi/pages/ManagedMultiFormPage.java @@ -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()); + } + } + + @Override + public boolean beforePost(HttpServletRequest req, HttpServletResponse resp) throws IOException { + return getForm(req).submitExceptionProtected(req, resp); + } + + public abstract Form getForm(HttpServletRequest req) throws CSRFException; + +} diff --git a/src/org/cacert/gigi/pages/OneFormPage.java b/src/org/cacert/gigi/pages/OneFormPage.java index cfcc1983..512dad49 100644 --- a/src/org/cacert/gigi/pages/OneFormPage.java +++ b/src/org/cacert/gigi/pages/OneFormPage.java @@ -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 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()); } } @@ -35,6 +40,4 @@ public abstract class OneFormPage extends Page { } } - public abstract String getSuccessPath(Form f); - } diff --git a/src/org/cacert/gigi/pages/Page.java b/src/org/cacert/gigi/pages/Page.java index 8d64d94f..054a1e52 100644 --- a/src/org/cacert/gigi/pages/Page.java +++ b/src/org/cacert/gigi/pages/Page.java @@ -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; } diff --git a/src/org/cacert/gigi/pages/PasswordResetPage.java b/src/org/cacert/gigi/pages/PasswordResetPage.java index 4090bdd4..580d0e54 100644 --- a/src/org/cacert/gigi/pages/PasswordResetPage.java +++ b/src/org/cacert/gigi/pages/PasswordResetPage.java @@ -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 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("
"); - w.println(HTMLEncoder.encodeHTML(getLanguage(req).getTranslation("Password reset successful."))); - w.println("
"); - return; + if (Form.printFormErrors(req, resp.getWriter())) { + PasswordResetForm form = Form.getForm(req, PasswordResetForm.class); + form.output(resp.getWriter(), getLanguage(req), new HashMap()); } } @@ -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(); } diff --git a/src/org/cacert/gigi/pages/Verify.java b/src/org/cacert/gigi/pages/Verify.java index 2a5950e9..d7e5aed6 100644 --- a/src/org/cacert/gigi/pages/Verify.java +++ b/src/org/cacert/gigi/pages/Verify.java @@ -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 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()); } } @@ -111,7 +117,6 @@ public class Verify extends Page { new VerificationForm(req).output(resp.getWriter(), getLanguage(req), new HashMap()); } catch (IllegalArgumentException e) { resp.getWriter().println(translate(req, "The object to verify is invalid.")); - } } diff --git a/src/org/cacert/gigi/pages/account/ChangeForm.java b/src/org/cacert/gigi/pages/account/ChangeForm.java index 667dc751..086c8a85 100644 --- a/src/org/cacert/gigi/pages/account/ChangeForm.java +++ b/src/org/cacert/gigi/pages/account/ChangeForm.java @@ -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.")); } } diff --git a/src/org/cacert/gigi/pages/account/ChangePasswordPage.java b/src/org/cacert/gigi/pages/account/ChangePasswordPage.java index 8432f027..60cfaa0b 100644 --- a/src/org/cacert/gigi/pages/account/ChangePasswordPage.java +++ b/src/org/cacert/gigi/pages/account/ChangePasswordPage.java @@ -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()); } - @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; diff --git a/src/org/cacert/gigi/pages/account/FindAgentAccess.java b/src/org/cacert/gigi/pages/account/FindAgentAccess.java index 98ee3ae3..47735f32 100644 --- a/src/org/cacert/gigi/pages/account/FindAgentAccess.java +++ b/src/org/cacert/gigi/pages/account/FindAgentAccess.java @@ -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 diff --git a/src/org/cacert/gigi/pages/account/MyDetails.java b/src/org/cacert/gigi/pages/account/MyDetails.java index bf80d47b..e6ba3ead 100644 --- a/src/org/cacert/gigi/pages/account/MyDetails.java +++ b/src/org/cacert/gigi/pages/account/MyDetails.java @@ -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()); + } + 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()); } } - super.doPost(req, resp); } } diff --git a/src/org/cacert/gigi/pages/account/MyDetailsForm.java b/src/org/cacert/gigi/pages/account/MyDetailsForm.java index 81390228..f5b6f514 100644 --- a/src/org/cacert/gigi/pages/account/MyDetailsForm.java +++ b/src/org/cacert/gigi/pages/account/MyDetailsForm.java @@ -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 diff --git a/src/org/cacert/gigi/pages/account/MyOrganisationsForm.java b/src/org/cacert/gigi/pages/account/MyOrganisationsForm.java index 706e9597..aaa84173 100644 --- a/src/org/cacert/gigi/pages/account/MyOrganisationsForm.java +++ b/src/org/cacert/gigi/pages/account/MyOrganisationsForm.java @@ -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 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 diff --git a/src/org/cacert/gigi/pages/account/certs/CertificateAdd.java b/src/org/cacert/gigi/pages/account/certs/CertificateAdd.java index e37b930c..b61ec3ec 100644 --- a/src/org/cacert/gigi/pages/account/certs/CertificateAdd.java +++ b/src/org/cacert/gigi/pages/account/certs/CertificateAdd.java @@ -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()); } - @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.emptyMap()); - - } - @Override public boolean isPermitted(AuthorizationContext ac) { return super.isPermitted(ac) && !ac.isInGroup(Group.BLOCKEDCERT); diff --git a/src/org/cacert/gigi/pages/account/certs/CertificateDisplay.templ b/src/org/cacert/gigi/pages/account/certs/CertificateDisplay.templ index c4bca81d..da3bef21 100644 --- a/src/org/cacert/gigi/pages/account/certs/CertificateDisplay.templ +++ b/src/org/cacert/gigi/pages/account/certs/CertificateDisplay.templ @@ -42,13 +42,15 @@ -
+ *





- .
+ . *

+ * 'FAQ!''!?> + diff --git a/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.java b/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.java index 0a95497d..8b9272cc 100644 --- a/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.java +++ b/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.java @@ -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"); diff --git a/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.templ b/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.templ index e9947a97..703bd98a 100644 --- a/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.templ +++ b/src/org/cacert/gigi/pages/account/certs/CertificateIssueForm.templ @@ -1,10 +1,17 @@ -

-

+

+

http://www.cacert.org/cps.php

- + + + + + + + + @@ -14,25 +21,37 @@ + - - - + + @@ -71,8 +90,9 @@ @@ -83,7 +103,10 @@ - +
- + - - + - + +
+ 'Verification Points (VP)!''.?>
- + + + +
+
SANs + + +
+ : dns:my.domain.example.com, dns:*.example.com, email:my.email@example.com
+ +
- +
+ https://secure.cacert.org/'.?>
+
+ + +
diff --git a/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java b/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java index fc367920..7c3f7840 100644 --- a/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java +++ b/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java @@ -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 revokes = new LinkedList(); 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 diff --git a/src/org/cacert/gigi/pages/account/certs/Certificates.java b/src/org/cacert/gigi/pages/account/certs/Certificates.java index 4db201cc..23cd915d 100644 --- a/src/org/cacert/gigi/pages/account/certs/Certificates.java +++ b/src/org/cacert/gigi/pages/account/certs/Certificates.java @@ -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()); } + 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()); } @Override diff --git a/src/org/cacert/gigi/pages/account/certs/RequestCertificate.templ b/src/org/cacert/gigi/pages/account/certs/RequestCertificate.templ index 9ffd5da6..32d327c2 100644 --- a/src/org/cacert/gigi/pages/account/certs/RequestCertificate.templ +++ b/src/org/cacert/gigi/pages/account/certs/RequestCertificate.templ @@ -1,3 +1,6 @@ +

+ 'FAQ'!'.?> +

@@ -7,9 +10,9 @@ - + @@ -21,19 +24,18 @@

'Wiki!''!?>
- +
-
- + diff --git a/src/org/cacert/gigi/pages/account/certs/RevokeSingleCertForm.java b/src/org/cacert/gigi/pages/account/certs/RevokeSingleCertForm.java index 5219081a..372b5568 100644 --- a/src/org/cacert/gigi/pages/account/certs/RevokeSingleCertForm.java +++ b/src/org/cacert/gigi/pages/account/certs/RevokeSingleCertForm.java @@ -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 diff --git a/src/org/cacert/gigi/pages/account/domain/DomainAddForm.java b/src/org/cacert/gigi/pages/account/domain/DomainAddForm.java index a0e5685b..58482179 100644 --- a/src/org/cacert/gigi/pages/account/domain/DomainAddForm.java +++ b/src/org/cacert/gigi/pages/account/domain/DomainAddForm.java @@ -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"); } } diff --git a/src/org/cacert/gigi/pages/account/domain/DomainManagementForm.java b/src/org/cacert/gigi/pages/account/domain/DomainManagementForm.java index 568c8a3a..c6ea009f 100644 --- a/src/org/cacert/gigi/pages/account/domain/DomainManagementForm.java +++ b/src/org/cacert/gigi/pages/account/domain/DomainManagementForm.java @@ -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")); diff --git a/src/org/cacert/gigi/pages/account/domain/DomainOverview.java b/src/org/cacert/gigi/pages/account/domain/DomainOverview.java index 97c47eeb..aa2043a1 100644 --- a/src/org/cacert/gigi/pages/account/domain/DomainOverview.java +++ b/src/org/cacert/gigi/pages/account/domain/DomainOverview.java @@ -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()); - try { - new PingConfigForm(req, d).output(resp.getWriter(), getLanguage(req), new HashMap()); - } catch (GigiApiException e) { - e.format(resp.getWriter(), getLanguage(req)); - } - return; - - } try { DomainManagementForm domMan = new DomainManagementForm(req, u, false); HashMap 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; } } diff --git a/src/org/cacert/gigi/pages/account/domain/DomainPinglogForm.java b/src/org/cacert/gigi/pages/account/domain/DomainPinglogForm.java index 525cd125..54209b20 100644 --- a/src/org/cacert/gigi/pages/account/domain/DomainPinglogForm.java +++ b/src/org/cacert/gigi/pages/account/domain/DomainPinglogForm.java @@ -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 index 00000000..f7df4903 --- /dev/null +++ b/src/org/cacert/gigi/pages/account/domain/EditDomain.java @@ -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()); + try { + new PingConfigForm(req, d).output(resp.getWriter(), getLanguage(req), new HashMap()); + } 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); + } + } + +} diff --git a/src/org/cacert/gigi/pages/account/domain/PingConfigForm.java b/src/org/cacert/gigi/pages/account/domain/PingConfigForm.java index 496bc4cf..6d23c3a0 100644 --- a/src/org/cacert/gigi/pages/account/domain/PingConfigForm.java +++ b/src/org/cacert/gigi/pages/account/domain/PingConfigForm.java @@ -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 diff --git a/src/org/cacert/gigi/pages/account/mail/MailAddForm.java b/src/org/cacert/gigi/pages/account/mail/MailAddForm.java index 1a67f8e2..47cd8384 100644 --- a/src/org/cacert/gigi/pages/account/mail/MailAddForm.java +++ b/src/org/cacert/gigi/pages/account/mail/MailAddForm.java @@ -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 diff --git a/src/org/cacert/gigi/pages/account/mail/MailManagementForm.java b/src/org/cacert/gigi/pages/account/mail/MailManagementForm.java index 9a399884..87087b74 100644 --- a/src/org/cacert/gigi/pages/account/mail/MailManagementForm.java +++ b/src/org/cacert/gigi/pages/account/mail/MailManagementForm.java @@ -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 diff --git a/src/org/cacert/gigi/pages/account/mail/MailOverview.java b/src/org/cacert/gigi/pages/account/mail/MailOverview.java index b828b718..ef98a091 100644 --- a/src/org/cacert/gigi/pages/account/mail/MailOverview.java +++ b/src/org/cacert/gigi/pages/account/mail/MailOverview.java @@ -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 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; } + } diff --git a/src/org/cacert/gigi/pages/admin/TTPAdminForm.java b/src/org/cacert/gigi/pages/admin/TTPAdminForm.java index ce6eecb3..2f3ee842 100644 --- a/src/org/cacert/gigi/pages/admin/TTPAdminForm.java +++ b/src/org/cacert/gigi/pages/admin/TTPAdminForm.java @@ -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 diff --git a/src/org/cacert/gigi/pages/admin/TTPAdminPage.java b/src/org/cacert/gigi/pages/admin/TTPAdminPage.java index bf773cb4..286a08d5 100644 --- a/src/org/cacert/gigi/pages/admin/TTPAdminPage.java +++ b/src/org/cacert/gigi/pages/admin/TTPAdminPage.java @@ -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()); } } diff --git a/src/org/cacert/gigi/pages/admin/support/FindCertForm.java b/src/org/cacert/gigi/pages/admin/support/FindCertForm.java index 07d9b929..207a2a8a 100644 --- a/src/org/cacert/gigi/pages/admin/support/FindCertForm.java +++ b/src/org/cacert/gigi/pages/admin/support/FindCertForm.java @@ -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 diff --git a/src/org/cacert/gigi/pages/admin/support/FindCertPage.java b/src/org/cacert/gigi/pages/admin/support/FindCertPage.java index 2e1f9134..e7f6b95e 100644 --- a/src/org/cacert/gigi/pages/admin/support/FindCertPage.java +++ b/src/org/cacert/gigi/pages/admin/support/FindCertPage.java @@ -33,11 +33,15 @@ public class FindCertPage extends Page { new FindCertForm(req).output(resp.getWriter(), Page.getLanguage(req), new HashMap()); } + @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 { diff --git a/src/org/cacert/gigi/pages/admin/support/FindUserByDomainForm.java b/src/org/cacert/gigi/pages/admin/support/FindUserByDomainForm.java index cce4aa0d..9aae4470 100644 --- a/src/org/cacert/gigi/pages/admin/support/FindUserByDomainForm.java +++ b/src/org/cacert/gigi/pages/admin/support/FindUserByDomainForm.java @@ -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 diff --git a/src/org/cacert/gigi/pages/admin/support/FindUserByDomainPage.java b/src/org/cacert/gigi/pages/admin/support/FindUserByDomainPage.java index 3572d3e6..8a642180 100644 --- a/src/org/cacert/gigi/pages/admin/support/FindUserByDomainPage.java +++ b/src/org/cacert/gigi/pages/admin/support/FindUserByDomainPage.java @@ -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()); } @Override diff --git a/src/org/cacert/gigi/pages/admin/support/FindUserByEmailForm.java b/src/org/cacert/gigi/pages/admin/support/FindUserByEmailForm.java index 12c33e97..2978c48e 100644 --- a/src/org/cacert/gigi/pages/admin/support/FindUserByEmailForm.java +++ b/src/org/cacert/gigi/pages/admin/support/FindUserByEmailForm.java @@ -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 vars) { t.output(out, l, vars); } - - public EmailAddress[] getEmails() { - return emails; - } - } diff --git a/src/org/cacert/gigi/pages/admin/support/FindUserByEmailPage.java b/src/org/cacert/gigi/pages/admin/support/FindUserByEmailPage.java index 15e6933e..9d731712 100644 --- a/src/org/cacert/gigi/pages/admin/support/FindUserByEmailPage.java +++ b/src/org/cacert/gigi/pages/admin/support/FindUserByEmailPage.java @@ -30,11 +30,17 @@ public class FindUserByEmailPage extends Page { new FindUserByEmailForm(req).output(resp.getWriter(), Page.getLanguage(req), new HashMap()); } + @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()); + } 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 { diff --git a/src/org/cacert/gigi/pages/admin/support/SupportEnterTicketForm.java b/src/org/cacert/gigi/pages/admin/support/SupportEnterTicketForm.java index 18afc0c6..e2e30a93 100644 --- a/src/org/cacert/gigi/pages/admin/support/SupportEnterTicketForm.java +++ b/src/org/cacert/gigi/pages/admin/support/SupportEnterTicketForm.java @@ -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 diff --git a/src/org/cacert/gigi/pages/admin/support/SupportEnterTicketPage.java b/src/org/cacert/gigi/pages/admin/support/SupportEnterTicketPage.java index eb1cfcab..01cc695f 100644 --- a/src/org/cacert/gigi/pages/admin/support/SupportEnterTicketPage.java +++ b/src/org/cacert/gigi/pages/admin/support/SupportEnterTicketPage.java @@ -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()); + } + } + @Override public boolean isPermitted(AuthorizationContext ac) { return ac != null && ac.isInGroup(Group.SUPPORTER); diff --git a/src/org/cacert/gigi/pages/admin/support/SupportRevokeCertificatesForm.java b/src/org/cacert/gigi/pages/admin/support/SupportRevokeCertificatesForm.java index 9c1f3f5b..5b163cc4 100644 --- a/src/org/cacert/gigi/pages/admin/support/SupportRevokeCertificatesForm.java +++ b/src/org/cacert/gigi/pages/admin/support/SupportRevokeCertificatesForm.java @@ -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 diff --git a/src/org/cacert/gigi/pages/admin/support/SupportUserDetailsForm.java b/src/org/cacert/gigi/pages/admin/support/SupportUserDetailsForm.java index d3589c8e..88b9b03b 100644 --- a/src/org/cacert/gigi/pages/admin/support/SupportUserDetailsForm.java +++ b/src/org/cacert/gigi/pages/admin/support/SupportUserDetailsForm.java @@ -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 diff --git a/src/org/cacert/gigi/pages/admin/support/SupportUserDetailsPage.java b/src/org/cacert/gigi/pages/admin/support/SupportUserDetailsPage.java index 04898f8c..eea69f6d 100644 --- a/src/org/cacert/gigi/pages/admin/support/SupportUserDetailsPage.java +++ b/src/org/cacert/gigi/pages/admin/support/SupportUserDetailsPage.java @@ -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 vars = new HashMap(); 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; + } } diff --git a/src/org/cacert/gigi/pages/main/RegisterPage.java b/src/org/cacert/gigi/pages/main/RegisterPage.java index 30c42833..69dc4c10 100644 --- a/src/org/cacert/gigi/pages/main/RegisterPage.java +++ b/src/org/cacert/gigi/pages/main/RegisterPage.java @@ -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 vars = new HashMap(); - getDefaultTemplate().output(out, getLanguage(req), vars); - s.output(out, getLanguage(req), vars); + getDefaultTemplate().output(resp.getWriter(), getLanguage(req), new HashMap()); + s.output(resp.getWriter(), getLanguage(req), new HashMap()); + } + + @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 diff --git a/src/org/cacert/gigi/pages/main/Signup.java b/src/org/cacert/gigi/pages/main/Signup.java index 819bfd5b..011b6384 100644 --- a/src/org/cacert/gigi/pages/main/Signup.java +++ b/src/org/cacert/gigi/pages/main/Signup.java @@ -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 { diff --git a/src/org/cacert/gigi/pages/orga/AffiliationForm.java b/src/org/cacert/gigi/pages/orga/AffiliationForm.java index cef4dc91..42682fed 100644 --- a/src/org/cacert/gigi/pages/orga/AffiliationForm.java +++ b/src/org/cacert/gigi/pages/orga/AffiliationForm.java @@ -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; - } } diff --git a/src/org/cacert/gigi/pages/orga/CreateOrgForm.java b/src/org/cacert/gigi/pages/orga/CreateOrgForm.java index 36bbbe8e..4abcafa3 100644 --- a/src/org/cacert/gigi/pages/orga/CreateOrgForm.java +++ b/src/org/cacert/gigi/pages/orga/CreateOrgForm.java @@ -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 vars) { vars.put("O", o); diff --git a/src/org/cacert/gigi/pages/orga/CreateOrgPage.java b/src/org/cacert/gigi/pages/orga/CreateOrgPage.java index 249871f2..17d2a318 100644 --- a/src/org/cacert/gigi/pages/orga/CreateOrgPage.java +++ b/src/org/cacert/gigi/pages/orga/CreateOrgPage.java @@ -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()); diff --git a/src/org/cacert/gigi/pages/orga/OrgDomainAddForm.java b/src/org/cacert/gigi/pages/orga/OrgDomainAddForm.java index c18cf8f1..78e04b40 100644 --- a/src/org/cacert/gigi/pages/orga/OrgDomainAddForm.java +++ b/src/org/cacert/gigi/pages/orga/OrgDomainAddForm.java @@ -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 diff --git a/src/org/cacert/gigi/pages/orga/ViewOrgPage.java b/src/org/cacert/gigi/pages/orga/ViewOrgPage.java index d1d1d519..88776107 100644 --- a/src/org/cacert/gigi/pages/orga/ViewOrgPage.java +++ b/src/org/cacert/gigi/pages/orga/ViewOrgPage.java @@ -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 diff --git a/src/org/cacert/gigi/pages/wot/AssuranceForm.java b/src/org/cacert/gigi/pages/wot/AssuranceForm.java index 8ad735fb..b46dfdd5 100644 --- a/src/org/cacert/gigi/pages/wot/AssuranceForm.java +++ b/src/org/cacert/gigi/pages/wot/AssuranceForm.java @@ -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 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() { diff --git a/src/org/cacert/gigi/pages/wot/AssurePage.java b/src/org/cacert/gigi/pages/wot/AssurePage.java index 95ab35f0..8ce8f72b 100644 --- a/src/org/cacert/gigi/pages/wot/AssurePage.java +++ b/src/org/cacert/gigi/pages/wot/AssurePage.java @@ -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()); } return; } diff --git a/src/org/cacert/gigi/pages/wot/RequestTTPForm.java b/src/org/cacert/gigi/pages/wot/RequestTTPForm.java index 3a6f7fe4..7348346f 100644 --- a/src/org/cacert/gigi/pages/wot/RequestTTPForm.java +++ b/src/org/cacert/gigi/pages/wot/RequestTTPForm.java @@ -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 diff --git a/src/org/cacert/gigi/pages/wot/RequestTTPPage.java b/src/org/cacert/gigi/pages/wot/RequestTTPPage.java index 7e50059d..f4b739c4 100644 --- a/src/org/cacert/gigi/pages/wot/RequestTTPPage.java +++ b/src/org/cacert/gigi/pages/wot/RequestTTPPage.java @@ -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()); + } } @Override diff --git a/src/org/cacert/gigi/util/VerificationAgentEntered.templ b/src/org/cacert/gigi/util/VerificationAgentEntered.templ index b66e38c8..a17fc098 100644 --- a/src/org/cacert/gigi/util/VerificationAgentEntered.templ +++ b/src/org/cacert/gigi/util/VerificationAgentEntered.templ @@ -6,7 +6,7 @@ Subject: \ - + \ diff --git a/static/static/css/main.css b/static/static/css/main.css index f8cd0729..7bb2ee87 100644 --- a/static/static/css/main.css +++ b/static/static/css/main.css @@ -23,3 +23,6 @@ div.error-msgs p{ .summary-table td{ padding: 0 3px; } +.js-hint { + display: none; +} \ No newline at end of file diff --git a/static/static/js/expert.js b/static/static/js/expert.js index 731dddde..9c623e73 100644 --- a/static/static/js/expert.js +++ b/static/static/js/expert.js @@ -60,8 +60,83 @@ } } } + 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); diff --git a/tests/org/cacert/gigi/pages/account/TestCertificateAdd.java b/tests/org/cacert/gigi/pages/account/TestCertificateAdd.java index 4d6529db..cbce25d4 100644 --- a/tests/org/cacert/gigi/pages/account/TestCertificateAdd.java +++ b/tests/org/cacert/gigi/pages/account/TestCertificateAdd.java @@ -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())); } } diff --git a/tests/org/cacert/gigi/testUtils/ManagedTest.java b/tests/org/cacert/gigi/testUtils/ManagedTest.java index 01ee4c59..0c7aced4 100644 --- a/tests/org/cacert/gigi/testUtils/ManagedTest.java +++ b/tests/org/cacert/gigi/testUtils/ManagedTest.java @@ -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; } diff --git a/tests/org/cacert/gigi/testUtils/PingTest.java b/tests/org/cacert/gigi/testUtils/PingTest.java index 967fdb2d..55c5683a 100644 --- a/tests/org/cacert/gigi/testUtils/PingTest.java +++ b/tests/org/cacert/gigi/testUtils/PingTest.java @@ -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 { diff --git a/util-testing/org/cacert/gigi/localisation/conf.txt b/util-testing/org/cacert/gigi/localisation/conf.txt index 21b24525..30694f09 100644 --- a/util-testing/org/cacert/gigi/localisation/conf.txt +++ b/util-testing/org/cacert/gigi/localisation/conf.txt @@ -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 diff --git a/util-testing/org/cacert/gigi/util/SimpleSigner.java b/util-testing/org/cacert/gigi/util/SimpleSigner.java index 9a2fb107..f2b97d7b 100644 --- a/util-testing/org/cacert/gigi/util/SimpleSigner.java +++ b/util-testing/org/cacert/gigi/util/SimpleSigner.java @@ -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":
- + :