From 95840660b28dce27a38ed7de0b66634ec7f38ba2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Felix=20D=C3=B6rre?= Date: Thu, 4 Jun 2015 20:48:38 +0200 Subject: [PATCH] add: let a user revoke his certificates. --- src/org/cacert/gigi/Gigi.java | 3 +- .../gigi/dbObjects/CertificateProfile.java | 2 +- .../gigi/output/CertificateIterable.java | 1 + .../cacert/gigi/output/CertificateTable.templ | 6 +- .../cacert/gigi/output/template/Template.java | 2 +- .../gigi/pages/HandlesMixedRequest.java | 12 +++ .../certs/CertificateModificationForm.java | 73 +++++++++++++++++++ .../certs/CertificateModificationForm.templ | 2 + .../pages/account/certs/Certificates.java | 23 ++++-- 9 files changed, 111 insertions(+), 13 deletions(-) create mode 100644 src/org/cacert/gigi/pages/HandlesMixedRequest.java create mode 100644 src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java create mode 100644 src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.templ diff --git a/src/org/cacert/gigi/Gigi.java b/src/org/cacert/gigi/Gigi.java index ff7f39b5..d153758e 100644 --- a/src/org/cacert/gigi/Gigi.java +++ b/src/org/cacert/gigi/Gigi.java @@ -30,6 +30,7 @@ import org.cacert.gigi.output.SimpleMenuItem; import org.cacert.gigi.output.template.Form.CSRFException; import org.cacert.gigi.output.template.Outputable; import org.cacert.gigi.output.template.Template; +import org.cacert.gigi.pages.HandlesMixedRequest; import org.cacert.gigi.pages.LoginPage; import org.cacert.gigi.pages.LogoutPage; import org.cacert.gigi.pages.MainPage; @@ -337,7 +338,7 @@ public class Gigi extends HttpServlet { public void output(PrintWriter out, Language l, Map vars) { try { if (req.getMethod().equals("POST")) { - if (req.getQueryString() != null) { + if (req.getQueryString() != null && !(p instanceof HandlesMixedRequest)) { return; } p.doPost(req, resp); diff --git a/src/org/cacert/gigi/dbObjects/CertificateProfile.java b/src/org/cacert/gigi/dbObjects/CertificateProfile.java index 659ee117..43c1dd5c 100644 --- a/src/org/cacert/gigi/dbObjects/CertificateProfile.java +++ b/src/org/cacert/gigi/dbObjects/CertificateProfile.java @@ -14,7 +14,7 @@ import org.cacert.gigi.database.DatabaseConnection; import org.cacert.gigi.database.GigiPreparedStatement; import org.cacert.gigi.database.GigiResultSet; -public class CertificateProfile { +public class CertificateProfile implements IdCachable { private final int id; diff --git a/src/org/cacert/gigi/output/CertificateIterable.java b/src/org/cacert/gigi/output/CertificateIterable.java index e4ba804e..14a62130 100644 --- a/src/org/cacert/gigi/output/CertificateIterable.java +++ b/src/org/cacert/gigi/output/CertificateIterable.java @@ -33,6 +33,7 @@ public class CertificateIterable implements IterableDataset { vars.put("profile", c.getProfile().getVisibleName()); try { CertificateStatus st = c.getStatus(); + vars.put("isNotRevoked", st != CertificateStatus.REVOKED); if (st == CertificateStatus.ISSUED || st == CertificateStatus.REVOKED) { X509Certificate cert = c.cert(); vars.put("issued", DateSelector.getDateFormat().format(cert.getNotBefore())); diff --git a/src/org/cacert/gigi/output/CertificateTable.templ b/src/org/cacert/gigi/output/CertificateTable.templ index 1999897e..d48f05c7 100644 --- a/src/org/cacert/gigi/output/CertificateTable.templ +++ b/src/org/cacert/gigi/output/CertificateTable.templ @@ -1,4 +1,3 @@ -
@@ -15,7 +14,9 @@ - + @@ -29,4 +30,3 @@
+ +
-
diff --git a/src/org/cacert/gigi/output/template/Template.java b/src/org/cacert/gigi/output/template/Template.java index d49df9ae..8bcbc8f2 100644 --- a/src/org/cacert/gigi/output/template/Template.java +++ b/src/org/cacert/gigi/output/template/Template.java @@ -54,7 +54,7 @@ public class Template implements Outputable { private File source; - private static final Pattern CONTROL_PATTERN = Pattern.compile(" ?([a-z]+)\\(\\$([^)]+)\\) ?\\{ ?"); + private static final Pattern CONTROL_PATTERN = Pattern.compile(" ?([a-zA-Z]+)\\(\\$([^)]+)\\) ?\\{ ?"); private static final Pattern ELSE_PATTERN = Pattern.compile(" ?\\} ?else ?\\{ ?"); diff --git a/src/org/cacert/gigi/pages/HandlesMixedRequest.java b/src/org/cacert/gigi/pages/HandlesMixedRequest.java new file mode 100644 index 00000000..5e15d384 --- /dev/null +++ b/src/org/cacert/gigi/pages/HandlesMixedRequest.java @@ -0,0 +1,12 @@ +package org.cacert.gigi.pages; + +import javax.servlet.http.HttpServletRequest; + +/** + * Marks a {@link Page} as beeing able to handle + * {@link HttpServletRequest#getQueryString()} in + * {@link HttpServletRequest#getMethod()}== "POST" + */ +public interface HandlesMixedRequest { + +} diff --git a/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java b/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java new file mode 100644 index 00000000..14e6c2fb --- /dev/null +++ b/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java @@ -0,0 +1,73 @@ +package org.cacert.gigi.pages.account.certs; + +import java.io.PrintWriter; +import java.util.LinkedList; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.cacert.gigi.dbObjects.Certificate; +import org.cacert.gigi.dbObjects.User; +import org.cacert.gigi.localisation.Language; +import org.cacert.gigi.output.CertificateIterable; +import org.cacert.gigi.output.template.Form; +import org.cacert.gigi.output.template.Template; +import org.cacert.gigi.pages.LoginPage; +import org.cacert.gigi.util.Job; + +public class CertificateModificationForm extends Form { + + User target; + + final boolean withRevoked; + + public CertificateModificationForm(HttpServletRequest hsr, boolean withRevoked) { + super(hsr); + this.withRevoked = withRevoked; + target = LoginPage.getUser(hsr); + } + + private static final Template certTable = new Template(CertificateIterable.class.getResource("CertificateTable.templ")); + + private static final Template myTemplate = new Template(CertificateModificationForm.class.getResource("CertificateModificationForm.templ")); + + @Override + public boolean submit(PrintWriter out, HttpServletRequest req) { + String[] certs = req.getParameterValues("certs[]"); + if (certs == null) { + // nothing to do + return false; + } + LinkedList revokes = new LinkedList(); + for (String serial : certs) { + Certificate c = Certificate.getBySerial(serial); + if (c == null || c.getOwner() != target) { + continue; + } + revokes.add(c.revoke()); + } + long start = System.currentTimeMillis(); + for (Job job : revokes) { + try { + int toWait = (int) (60000 + start - System.currentTimeMillis()); + if (toWait > 0) { + job.waitFor(toWait); + } else { + break; // canceled... waited too log + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + return false; + } + + @Override + protected void outputContent(PrintWriter out, Language l, Map vars) { + vars.put("certs", new CertificateIterable(target.getCertificates(withRevoked))); + vars.put("certTable", certTable); + myTemplate.output(out, l, vars); + } + +} diff --git a/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.templ b/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.templ new file mode 100644 index 00000000..585513d1 --- /dev/null +++ b/src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.templ @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/org/cacert/gigi/pages/account/certs/Certificates.java b/src/org/cacert/gigi/pages/account/certs/Certificates.java index 5ae5ca63..799927fd 100644 --- a/src/org/cacert/gigi/pages/account/certs/Certificates.java +++ b/src/org/cacert/gigi/pages/account/certs/Certificates.java @@ -14,16 +14,16 @@ import javax.servlet.http.HttpServletResponse; import org.cacert.gigi.dbObjects.CACertificate; import org.cacert.gigi.dbObjects.Certificate; -import org.cacert.gigi.dbObjects.User; import org.cacert.gigi.localisation.Language; -import org.cacert.gigi.output.CertificateIterable; +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.HandlesMixedRequest; import org.cacert.gigi.pages.LoginPage; import org.cacert.gigi.pages.Page; import org.cacert.gigi.util.PEM; -public class Certificates extends Page { +public class Certificates extends Page implements HandlesMixedRequest { private Template certDisplay = new Template(Certificates.class.getResource("CertificateDisplay.templ")); @@ -120,7 +120,18 @@ public class Certificates extends Page { return true; } - private Template certTable = new Template(CertificateIterable.class.getResource("CertificateTable.templ")); + @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 ( !req.getPathInfo().equals(PATH)) { + resp.sendError(500); + return; + } + Form.getForm(req, CertificateModificationForm.class).submit(resp.getWriter(), req); + doGet(req, resp); + } @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { @@ -149,9 +160,7 @@ public class Certificates extends Page { } HashMap vars = new HashMap(); - User us = LoginPage.getUser(req); - vars.put("certs", new CertificateIterable(us.getCertificates(false))); - certTable.output(out, getLanguage(req), vars); + new CertificateModificationForm(req, req.getParameter("withRevoked") != null).output(out, getLanguage(req), vars); } } -- 2.39.2