]> WPIA git - gigi.git/commitdiff
add: let a user revoke his certificates.
authorFelix Dörre <felix@dogcraft.de>
Thu, 4 Jun 2015 18:48:38 +0000 (20:48 +0200)
committerFelix Dörre <felix@dogcraft.de>
Thu, 4 Jun 2015 18:59:32 +0000 (20:59 +0200)
src/org/cacert/gigi/Gigi.java
src/org/cacert/gigi/dbObjects/CertificateProfile.java
src/org/cacert/gigi/output/CertificateIterable.java
src/org/cacert/gigi/output/CertificateTable.templ
src/org/cacert/gigi/output/template/Template.java
src/org/cacert/gigi/pages/HandlesMixedRequest.java [new file with mode: 0644]
src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.java [new file with mode: 0644]
src/org/cacert/gigi/pages/account/certs/CertificateModificationForm.templ [new file with mode: 0644]
src/org/cacert/gigi/pages/account/certs/Certificates.java

index ff7f39b52fa9840b11c916a84e69288c7fdcc1b8..d153758ee31037dfaaf3d5b5794f01b13d27e50c 100644 (file)
@@ -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.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;
 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<String, Object> vars) {
                     try {
                         if (req.getMethod().equals("POST")) {
                 public void output(PrintWriter out, Language l, Map<String, Object> vars) {
                     try {
                         if (req.getMethod().equals("POST")) {
-                            if (req.getQueryString() != null) {
+                            if (req.getQueryString() != null && !(p instanceof HandlesMixedRequest)) {
                                 return;
                             }
                             p.doPost(req, resp);
                                 return;
                             }
                             p.doPost(req, resp);
index 659ee1176d8dec74f1af144cc126dc781ca17b85..43c1dd5ca3831d70161b25f23d6a7a03ff49d790 100644 (file)
@@ -14,7 +14,7 @@ import org.cacert.gigi.database.DatabaseConnection;
 import org.cacert.gigi.database.GigiPreparedStatement;
 import org.cacert.gigi.database.GigiResultSet;
 
 import org.cacert.gigi.database.GigiPreparedStatement;
 import org.cacert.gigi.database.GigiResultSet;
 
-public class CertificateProfile {
+public class CertificateProfile implements IdCachable {
 
     private final int id;
 
 
     private final int id;
 
index e4ba804eeec16dbd3d2fb9192513dea0510a5da8..14a62130d0ce64b2a998ace84b0741823c065abb 100644 (file)
@@ -33,6 +33,7 @@ public class CertificateIterable implements IterableDataset {
         vars.put("profile", c.getProfile().getVisibleName());
         try {
             CertificateStatus st = c.getStatus();
         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()));
             if (st == CertificateStatus.ISSUED || st == CertificateStatus.REVOKED) {
                 X509Certificate cert = c.cert();
                 vars.put("issued", DateSelector.getDateFormat().format(cert.getNotBefore()));
index 1999897ec3c6c4b95b08da923f3dd8d0dd56135c..d48f05c7e1dd3f95b1f233501db58b7022a659ed 100644 (file)
@@ -1,4 +1,3 @@
-<form method="post">
 <table class="wrapper dataTable">
 <thead><tr>
 <th><?=_Renew/Revoke/Delete?></th>
 <table class="wrapper dataTable">
 <thead><tr>
 <th><?=_Renew/Revoke/Delete?></th>
@@ -15,7 +14,9 @@
 <tbody>
 <? foreach($certs) {?>
 <tr>
 <tbody>
 <? foreach($certs) {?>
 <tr>
-       <td><input type='checkbox' name='certs[]' value='<?=$serial?>'></td>
+       <td>
+       <? if($isNotRevoked) { ?><input type='checkbox' name='certs[]' value='<?=$serial?>'><? } ?>
+       </td>
        <td><?=$state?></td>
        <td><?=$CN?></td>
        <td><a href='/account/certs/<?=$serial?>'><?=$serial?></a></td>
        <td><?=$state?></td>
        <td><?=$CN?></td>
        <td><a href='/account/certs/<?=$serial?>'><?=$serial?></a></td>
@@ -29,4 +30,3 @@
 <? } ?>
 </tbody>
 </table>
 <? } ?>
 </tbody>
 </table>
-</form>
index d49df9ae2c5a4c8600a0f48e631b1ed9caf91f0b..8bcbc8f24ebe156a98d5cdd38918e494e94c004d 100644 (file)
@@ -54,7 +54,7 @@ public class Template implements Outputable {
 
     private File source;
 
 
     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 ?\\{ ?");
 
 
     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 (file)
index 0000000..5e15d38
--- /dev/null
@@ -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()}<code>== "POST"</code>
+ */
+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 (file)
index 0000000..14e6c2f
--- /dev/null
@@ -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<Job> revokes = new LinkedList<Job>();
+        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<String, Object> 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 (file)
index 0000000..585513d
--- /dev/null
@@ -0,0 +1,2 @@
+<?=$certTable?>
+<input type="submit" value="<?=_Revoke Certificates?>"/>
\ No newline at end of file
index 5ae5ca63cdb8ea694f87784c658a0503f327aa33..799927fdb1ca21e6c390f06074c74231e7ad3bc3 100644 (file)
@@ -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.CACertificate;
 import org.cacert.gigi.dbObjects.Certificate;
-import org.cacert.gigi.dbObjects.User;
 import org.cacert.gigi.localisation.Language;
 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.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;
 
 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"));
 
 
     private Template certDisplay = new Template(Certificates.class.getResource("CertificateDisplay.templ"));
 
@@ -120,7 +120,18 @@ public class Certificates extends Page {
         return true;
     }
 
         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 {
 
     @Override
     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
@@ -149,9 +160,7 @@ public class Certificates extends Page {
         }
 
         HashMap<String, Object> vars = new HashMap<String, Object>();
         }
 
         HashMap<String, Object> vars = new HashMap<String, Object>();
-        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);
     }
 
 }
     }
 
 }