From 2f50dbb24105e6345329b8e9ecb5ef4d67ab2a8c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Felix=20D=C3=B6rre?= Date: Mon, 4 Jul 2016 10:47:02 +0200 Subject: [PATCH] upd: better display of (and collection of) error messages Change-Id: I74654fab8f88f5e15bf4c1c424b8709b504affe2 --- src/org/cacert/gigi/GigiApiException.java | 10 ++-- src/org/cacert/gigi/output/template/Form.java | 36 ------------ .../gigi/output/template/PlainOutputable.java | 22 +++++++ src/org/cacert/gigi/pages/LoginPage.java | 16 ++++- .../gigi/pages/account/mail/MailAddForm.java | 9 +-- .../gigi/pages/account/mail/MailOverview.java | 9 ++- .../cacert/gigi/pages/main/RegisterPage.java | 17 +++--- src/org/cacert/gigi/pages/main/Signup.java | 58 +++++++++---------- .../cacert/gigi/pages/wot/AssuranceForm.java | 37 +++++------- src/org/cacert/gigi/pages/wot/AssurePage.java | 21 ++++--- src/org/cacert/gigi/util/RateLimit.java | 9 +++ static/static/css/cacert.css | 3 + .../pages/account/TestCertificateAdd.java | 17 ++++-- .../cacert/gigi/testUtils/ManagedTest.java | 2 +- 14 files changed, 140 insertions(+), 126 deletions(-) create mode 100644 src/org/cacert/gigi/output/template/PlainOutputable.java diff --git a/src/org/cacert/gigi/GigiApiException.java b/src/org/cacert/gigi/GigiApiException.java index 0d600b97..a61b4b5c 100644 --- a/src/org/cacert/gigi/GigiApiException.java +++ b/src/org/cacert/gigi/GigiApiException.java @@ -51,20 +51,20 @@ public class GigiApiException extends Exception { } public void format(PrintWriter out, Language language) { - out.println("
"); + out.println("
"); if (isInternalError()) { e.printStackTrace(); - out.print("
"); + out.print("

"); out.println(language.getTranslation("An internal error occurred.")); - out.println("

"); + out.println("

"); } HashMap map = new HashMap<>(); for (Outputable message : messages) { map.clear(); - out.print("
"); + out.print("

"); message.output(out, language, map); - out.println("

"); + out.println("

"); } out.println("
"); diff --git a/src/org/cacert/gigi/output/template/Form.java b/src/org/cacert/gigi/output/template/Form.java index 83a96f38..f2219581 100644 --- a/src/org/cacert/gigi/output/template/Form.java +++ b/src/org/cacert/gigi/output/template/Form.java @@ -4,13 +4,11 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.Map; -import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.cacert.gigi.GigiApiException; import org.cacert.gigi.localisation.Language; -import org.cacert.gigi.pages.Page; import org.cacert.gigi.util.RandomToken; /** @@ -73,7 +71,6 @@ public abstract class Form implements Outputable { } else { out.println("
"); } - failed = false; outputContent(out, l, vars); out.print(""); - } - out.print("
"); - if (contents.length == 0) { - out.print(Page.translate(req, text)); - } else { - out.print(String.format(Page.translate(req, text), contents)); - } - out.println("
"); - } - - protected void outputErrorPlain(PrintWriter out, String text) { - if ( !failed) { - failed = true; - out.println("
"); - } - out.print("
"); - out.print(text); - out.println("
"); - } - - public boolean isFailed(PrintWriter out) { - if (failed) { - out.println("
"); - } - return failed; - } - protected String getCSRFToken() { return csrf; } diff --git a/src/org/cacert/gigi/output/template/PlainOutputable.java b/src/org/cacert/gigi/output/template/PlainOutputable.java new file mode 100644 index 00000000..1ab34975 --- /dev/null +++ b/src/org/cacert/gigi/output/template/PlainOutputable.java @@ -0,0 +1,22 @@ +package org.cacert.gigi.output.template; + +import java.io.PrintWriter; +import java.util.Map; + +import org.cacert.gigi.localisation.Language; +import org.cacert.gigi.util.HTMLEncoder; + +public class PlainOutputable implements Outputable { + + String text; + + public PlainOutputable(String text) { + this.text = HTMLEncoder.encodeHTML(text); + } + + @Override + public void output(PrintWriter out, Language l, Map vars) { + out.print(text); + } + +} diff --git a/src/org/cacert/gigi/pages/LoginPage.java b/src/org/cacert/gigi/pages/LoginPage.java index 141c6ca1..c206ad44 100644 --- a/src/org/cacert/gigi/pages/LoginPage.java +++ b/src/org/cacert/gigi/pages/LoginPage.java @@ -25,6 +25,7 @@ import org.cacert.gigi.pages.main.RegisterPage; import org.cacert.gigi.util.AuthorizationContext; import org.cacert.gigi.util.PasswordHash; import org.cacert.gigi.util.RateLimit; +import org.cacert.gigi.util.RateLimit.RateLimitException; import org.cacert.gigi.util.ServerConstants; public class LoginPage extends Page { @@ -40,8 +41,7 @@ public class LoginPage extends Page { @Override public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException { if (RegisterPage.RATE_LIMIT.isLimitExceeded(req.getRemoteAddr())) { - outputError(out, req, "Rate Limit Exceeded"); - return false; + throw new RateLimitException(); } tryAuthWithUnpw(req); return false; @@ -56,12 +56,18 @@ 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 { @@ -81,6 +87,8 @@ public class LoginPage extends Page { try { Form.getForm(req, LoginForm.class).submit(resp.getWriter(), req); } catch (GigiApiException e) { + req.setAttribute(SUBMIT_EXCEPTION, e); + return false; } } } @@ -105,7 +113,7 @@ public class LoginPage extends Page { return false; } - private void tryAuthWithUnpw(HttpServletRequest req) { + private void tryAuthWithUnpw(HttpServletRequest req) throws GigiApiException { String un = req.getParameter("username"); String pw = req.getParameter("password"); try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT `password`, `id` FROM `users` WHERE `email`=? AND verified='1'")) { @@ -124,9 +132,11 @@ public class LoginPage extends Page { } loginSession(req, User.getById(rs.getInt(2))); req.getSession().setAttribute(LOGIN_METHOD, new TranslateCommand("Password")); + return; } } } + throw new GigiApiException("Username and password didn't match."); } public static User getUser(HttpServletRequest req) { diff --git a/src/org/cacert/gigi/pages/account/mail/MailAddForm.java b/src/org/cacert/gigi/pages/account/mail/MailAddForm.java index 6a2bb2c5..eaf35f40 100644 --- a/src/org/cacert/gigi/pages/account/mail/MailAddForm.java +++ b/src/org/cacert/gigi/pages/account/mail/MailAddForm.java @@ -10,6 +10,7 @@ import org.cacert.gigi.dbObjects.EmailAddress; 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.PlainOutputable; import org.cacert.gigi.output.template.Template; import org.cacert.gigi.pages.Page; @@ -30,17 +31,13 @@ public class MailAddForm extends Form { } @Override - public boolean submit(PrintWriter out, HttpServletRequest req) { + public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException { String formMail = req.getParameter("newemail"); mail = formMail; try { new EmailAddress(target, mail, Page.getLanguage(req).getLocale()); } catch (IllegalArgumentException e) { - out.println("
Error: Invalid address!
"); - return false; - } catch (GigiApiException e) { - e.format(out, Page.getLanguage(req)); - return false; + throw new GigiApiException(new PlainOutputable("Invalid address.")); } return true; } diff --git a/src/org/cacert/gigi/pages/account/mail/MailOverview.java b/src/org/cacert/gigi/pages/account/mail/MailOverview.java index da3befd5..b828b718 100644 --- a/src/org/cacert/gigi/pages/account/mail/MailOverview.java +++ b/src/org/cacert/gigi/pages/account/mail/MailOverview.java @@ -7,6 +7,7 @@ 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; @@ -36,8 +37,12 @@ public class MailOverview extends Page { PrintWriter out = resp.getWriter(); if (req.getParameter("addmail") != null) { MailAddForm f = Form.getForm(req, MailAddForm.class); - if (f.submit(out, req)) { - resp.sendRedirect(MailOverview.DEFAULT_PATH); + try { + if (f.submit(out, req)) { + resp.sendRedirect(MailOverview.DEFAULT_PATH); + } + } catch (GigiApiException e) { + e.format(resp.getWriter(), getLanguage(req)); } } else { MailManagementForm f = Form.getForm(req, MailManagementForm.class); diff --git a/src/org/cacert/gigi/pages/main/RegisterPage.java b/src/org/cacert/gigi/pages/main/RegisterPage.java index 1e6b3378..30c42833 100644 --- a/src/org/cacert/gigi/pages/main/RegisterPage.java +++ b/src/org/cacert/gigi/pages/main/RegisterPage.java @@ -8,6 +8,7 @@ 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; @@ -42,13 +43,15 @@ public class RegisterPage extends Page { @Override public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { Signup s = Form.getForm(req, Signup.class); - if (s == null) { - resp.getWriter().println(translate(req, "CSRF token check failed.")); - } else 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; + 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)); } outputGet(req, resp, s); diff --git a/src/org/cacert/gigi/pages/main/Signup.java b/src/org/cacert/gigi/pages/main/Signup.java index d341df28..4df3ba49 100644 --- a/src/org/cacert/gigi/pages/main/Signup.java +++ b/src/org/cacert/gigi/pages/main/Signup.java @@ -2,7 +2,6 @@ package org.cacert.gigi.pages.main; import java.io.IOException; import java.io.PrintWriter; -import java.sql.SQLException; import java.util.HashMap; import java.util.Map; @@ -17,12 +16,15 @@ import org.cacert.gigi.email.EmailProvider; import org.cacert.gigi.localisation.Language; import org.cacert.gigi.output.DateSelector; 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.pages.Page; import org.cacert.gigi.util.CalendarUtil; import org.cacert.gigi.util.HTMLEncoder; import org.cacert.gigi.util.Notary; import org.cacert.gigi.util.PasswordStrengthChecker; +import org.cacert.gigi.util.RateLimit.RateLimitException; public class Signup extends Form { @@ -92,51 +94,52 @@ public class Signup extends Form { } @Override - public synchronized boolean submit(PrintWriter out, HttpServletRequest req) { + public synchronized boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException { if (RegisterPage.RATE_LIMIT.isLimitExceeded(req.getRemoteAddr())) { - outputError(out, req, "Rate Limit Exceeded"); - return false; + throw new RateLimitException(); } update(req); + GigiApiException ga = new GigiApiException(); if (buildupName.getLname().trim().equals("")) { - outputError(out, req, "Last name were blank."); + ga.mergeInto(new GigiApiException("Last name were blank.")); } if ( !myDoB.isValid()) { - outputError(out, req, "Invalid date of birth"); + ga.mergeInto(new GigiApiException("Invalid date of birth")); } if ( !CalendarUtil.isOfAge(myDoB.getDate(), User.MINIMUM_AGE)) { - outputError(out, req, "Entered dated of birth is below the restricted age requirements."); + ga.mergeInto(new GigiApiException("Entered dated of birth is below the restricted age requirements.")); } if ( !"1".equals(req.getParameter("tos_agree"))) { - outputError(out, req, "Acceptance of the ToS is required to continue."); + ga.mergeInto(new GigiApiException("Acceptance of the ToS is required to continue.")); } if (email.equals("")) { - outputError(out, req, "Email Address was blank"); + ga.mergeInto(new GigiApiException("Email Address was blank")); } String pw1 = req.getParameter("pword1"); String pw2 = req.getParameter("pword2"); if (pw1 == null || pw1.equals("")) { - outputError(out, req, "Pass Phrases were blank"); + ga.mergeInto(new GigiApiException("Pass Phrases were blank")); } else if ( !pw1.equals(pw2)) { - outputError(out, req, "Pass Phrases don't match"); + ga.mergeInto(new GigiApiException("Pass Phrases don't match")); } int pwpoints = PasswordStrengthChecker.checkpw(pw1, buildupName, email); if (pwpoints < 3) { - outputError(out, req, "The Pass Phrase you submitted failed to contain enough" + " differing characters and/or contained words from" + " your name and/or email address."); + ga.mergeInto(new GigiApiException("The Pass Phrase you submitted failed to contain enough" + " differing characters and/or contained words from" + " your name and/or email address.")); } - if (isFailed(out)) { - return false; + if ( !ga.isEmpty()) { + throw ga; } + GigiApiException ga2 = new GigiApiException(); try (GigiPreparedStatement q1 = new GigiPreparedStatement("SELECT * FROM `emails` WHERE `email`=? AND `deleted` IS NULL"); GigiPreparedStatement q2 = new GigiPreparedStatement("SELECT * FROM `certOwners` INNER JOIN `users` ON `users`.`id`=`certOwners`.`id` WHERE `email`=? AND `deleted` IS NULL")) { q1.setString(1, email); q2.setString(1, email); GigiResultSet r1 = q1.executeQuery(); GigiResultSet r2 = q2.executeQuery(); if (r1.next() || r2.next()) { - outputError(out, req, "This email address is currently valid in the system."); + ga2.mergeInto(new GigiApiException("This email address is currently valid in the system.")); } } try (GigiPreparedStatement q3 = new GigiPreparedStatement("SELECT `domain` FROM `baddomains` WHERE `domain`=RIGHT(?, LENGTH(`domain`))")) { @@ -145,7 +148,7 @@ public class Signup extends Form { GigiResultSet r3 = q3.executeQuery(); if (r3.next()) { String domain = r3.getString(1); - outputError(out, req, "We don't allow signups from people using email addresses from %s", domain); + ga2.mergeInto(new GigiApiException(SprintfCommand.createSimple("We don't allow signups from people using email addresses from {0}.", domain))); } } String mailResult = EmailProvider.FAIL; @@ -155,32 +158,25 @@ public class Signup extends Form { } if ( !mailResult.equals(EmailProvider.OK)) { if (mailResult.startsWith("4")) { - outputError(out, req, "The mail server responsible for your domain indicated" + " a temporary failure. This may be due to anti-SPAM measures, such" + " as greylisting. Please try again in a few minutes."); + ga2.mergeInto(new GigiApiException("The mail server responsible for your domain indicated" + " a temporary failure. This may be due to anti-SPAM measures, such" + " as greylisting. Please try again in a few minutes.")); } else { - outputError(out, req, "Email Address given was invalid, or a test connection" + " couldn't be made to your server, or the server" + " rejected the email address as invalid"); + ga2.mergeInto(new GigiApiException("Email Address given was invalid, or a test connection" + " couldn't be made to your server, or the server" + " rejected the email address as invalid")); } if (mailResult.equals(EmailProvider.FAIL)) { - outputError(out, req, "Failed to make a connection to the mail server"); + ga2.mergeInto(new GigiApiException("Failed to make a connection to the mail server")); } else { - outputErrorPlain(out, mailResult); + ga2.mergeInto(new GigiApiException(new PlainOutputable(mailResult))); } } - if (isFailed(out)) { - return false; - } - try { - run(req, pw1); - } catch (SQLException e) { - e.printStackTrace(); - } catch (GigiApiException e) { - e.format(out, Page.getLanguage(req)); - return false; + if ( !ga2.isEmpty()) { + throw ga2; } + run(req, pw1); return true; } - private void run(HttpServletRequest req, String password) throws SQLException, GigiApiException { + private void run(HttpServletRequest req, String password) throws GigiApiException { User u = new User(email, password, buildupName, myDoB.getDate(), Page.getLanguage(req).getLocale()); try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `alerts` SET `memid`=?," + " `general`=?, `country`=?, `regional`=?, `radius`=?")) { diff --git a/src/org/cacert/gigi/pages/wot/AssuranceForm.java b/src/org/cacert/gigi/pages/wot/AssuranceForm.java index 79f4d509..15642403 100644 --- a/src/org/cacert/gigi/pages/wot/AssuranceForm.java +++ b/src/org/cacert/gigi/pages/wot/AssuranceForm.java @@ -97,15 +97,16 @@ public class AssuranceForm extends Form { } @Override - public boolean submit(PrintWriter out, HttpServletRequest req) { + public boolean submit(PrintWriter out, HttpServletRequest req) throws GigiApiException { location = req.getParameter("location"); date = req.getParameter("date"); + GigiApiException gae = new GigiApiException(); if (date == null || location == null) { - outputError(out, req, "You need to enter location and date!"); + gae.mergeInto(new GigiApiException("You need to enter location and date!")); } if ( !"1".equals(req.getParameter("certify")) || !"1".equals(req.getParameter("rules")) || !"1".equals(req.getParameter("tos_agree")) || !"1".equals(req.getParameter("assertion"))) { - outputError(out, req, "You failed to check all boxes to validate" + " your adherence to the rules and policies of SomeCA"); + gae.mergeInto(new GigiApiException("You failed to check all boxes to validate" + " your adherence to the rules and policies of SomeCA")); } if ("1".equals(req.getParameter("passwordReset"))) { aword = req.getParameter("passwordResetValue"); @@ -120,39 +121,33 @@ public class AssuranceForm extends Form { try { type = AssuranceType.valueOf(val); } catch (IllegalArgumentException e) { - outputError(out, req, "Assurance Type wrong."); + gae.mergeInto(new GigiApiException("Assurance Type wrong.")); } } int pointsI = 0; String points = req.getParameter("points"); if (points == null || "".equals(points)) { - outputError(out, req, "For an assurance, you need to enter points."); + gae.mergeInto(new GigiApiException("For an assurance, you need to enter points.")); } else { try { pointsI = Integer.parseInt(points); } catch (NumberFormatException e) { - outputError(out, req, "The points entered were not a number."); + gae.mergeInto(new GigiApiException("The points entered were not a number.")); } } - if (isFailed(out)) { - return false; + if ( !gae.isEmpty()) { + throw gae; } - try { - Notary.assure(assurer, assuree, assureeName, dob, pointsI, location, req.getParameter("date"), type); - if (aword != null && !aword.equals("")) { - Language l = Language.getInstance(assuree.getPreferredLocale()); - String method = l.getTranslation("A password reset was triggered. If you did a password reset by assurance, please enter your secret password using this form:"); - String subject = l.getTranslation("Password reset by assurance"); - PasswordResetPage.initPasswordResetProcess(out, assuree, req, aword, l, method, subject); - } - return true; - } catch (GigiApiException e) { - e.format(out, Page.getLanguage(req)); + Notary.assure(assurer, assuree, assureeName, dob, pointsI, location, req.getParameter("date"), type); + if (aword != null && !aword.equals("")) { + Language l = Language.getInstance(assuree.getPreferredLocale()); + String method = l.getTranslation("A password reset was triggered. If you did a password reset by assurance, please enter your secret password using this form:"); + String subject = l.getTranslation("Password reset by assurance"); + PasswordResetPage.initPasswordResetProcess(out, assuree, req, aword, l, method, subject); } - - return false; + return true; } public User getAssuree() { diff --git a/src/org/cacert/gigi/pages/wot/AssurePage.java b/src/org/cacert/gigi/pages/wot/AssurePage.java index 94c582f2..e0cb4a21 100644 --- a/src/org/cacert/gigi/pages/wot/AssurePage.java +++ b/src/org/cacert/gigi/pages/wot/AssurePage.java @@ -54,14 +54,18 @@ public class AssurePage extends Page { PrintWriter out = resp.getWriter(); if (req.getParameter("search") == null) { AssuranceForm form = Form.getForm(req, AssuranceForm.class); - if (form.submit(out, req)) { - out.println(translate(req, "Assurance complete.")); - } else { + try { + if (form.submit(out, req)) { + out.println(translate(req, "Assurance complete.")); + return; + } + } catch (GigiApiException e) { + e.format(out, Page.getLanguage(req)); try { Notary.checkAssuranceIsPossible(LoginPage.getUser(req), form.getAssuree()); form.output(out, getLanguage(req), new HashMap()); - } catch (GigiApiException e) { - e.format(out, Page.getLanguage(req)); + } catch (GigiApiException e1) { + e1.format(out, Page.getLanguage(req)); } } @@ -97,10 +101,9 @@ public class AssurePage extends Page { } } } else { - out.print("
"); - - out.println(translate(req, "I'm sorry, there was no email and date of birth matching" + " what you entered in the system. Please double check" + " your information.")); - out.print("
"); + GigiApiException e = new GigiApiException("I'm sorry, there was no email and date of birth matching" // + + " what you entered in the system. Please double check your information."); + e.format(out, getLanguage(req)); } } diff --git a/src/org/cacert/gigi/util/RateLimit.java b/src/org/cacert/gigi/util/RateLimit.java index 65c16684..eb24563d 100644 --- a/src/org/cacert/gigi/util/RateLimit.java +++ b/src/org/cacert/gigi/util/RateLimit.java @@ -3,8 +3,17 @@ package org.cacert.gigi.util; import java.util.HashMap; import java.util.TreeSet; +import org.cacert.gigi.GigiApiException; + public class RateLimit { + public static final class RateLimitException extends GigiApiException { + + public RateLimitException() { + super("Rate limit exceeded."); + } + } + private class Entry implements Comparable { long firstAccess; diff --git a/static/static/css/cacert.css b/static/static/css/cacert.css index b9443976..34db4f10 100644 --- a/static/static/css/cacert.css +++ b/static/static/css/cacert.css @@ -17,3 +17,6 @@ .experthidden{ display: none; } +div.error-msgs p{ + padding: 6px; +} diff --git a/tests/org/cacert/gigi/pages/account/TestCertificateAdd.java b/tests/org/cacert/gigi/pages/account/TestCertificateAdd.java index 57a5e634..fba274d1 100644 --- a/tests/org/cacert/gigi/pages/account/TestCertificateAdd.java +++ b/tests/org/cacert/gigi/pages/account/TestCertificateAdd.java @@ -56,6 +56,13 @@ import sun.security.x509.X509Key; public class TestCertificateAdd extends ClientTest { + private static class OnPageError extends Error { + + public OnPageError(String page) { + super(page); + } + } + KeyPair kp = generateKeypair(); String csrf; @@ -295,8 +302,9 @@ public class TestCertificateAdd extends ClientTest { assertArrayEquals(new String[] { "client", CertificateRequest.DEFAULT_CN, "", Digest.SHA512.toString() }, res); - } catch (Error e) { - assertTrue(e.getMessage().startsWith("
Challenge mismatch")); + } catch (OnPageError e) { + String error = fetchStartErrorMessage(e.getMessage()); + assertTrue(error, error.startsWith("

Challenge mismatch")); } return csrf; } @@ -341,9 +349,8 @@ public class TestCertificateAdd extends ClientTest { private String[] extractFormData(HttpURLConnection uc) throws IOException, Error { String result = IOUtils.readURL(uc); - if (result.contains("

")) { - String s = fetchStartErrorMessage(result); - throw new Error(s); + if (result.contains("
")) { + throw new OnPageError(result); } String profileKey = extractPattern(result, Pattern.compile("