aboutsummaryrefslogtreecommitdiff
path: root/src/main/ui/gui/RevokeDialog.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/ui/gui/RevokeDialog.java')
-rw-r--r--src/main/ui/gui/RevokeDialog.java184
1 files changed, 184 insertions, 0 deletions
diff --git a/src/main/ui/gui/RevokeDialog.java b/src/main/ui/gui/RevokeDialog.java
new file mode 100644
index 0000000..9cebc74
--- /dev/null
+++ b/src/main/ui/gui/RevokeDialog.java
@@ -0,0 +1,184 @@
+package ui.gui;
+
+import model.asn1.ASN1Object;
+import model.asn1.UtcTime;
+import model.pki.cert.Certificate;
+import model.pki.crl.Reason;
+import model.pki.crl.RevokedCertificate;
+import ui.gui.widgets.GCBuilder;
+import ui.gui.widgets.UIUtils;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.util.Arrays;
+
+import static java.awt.GridBagConstraints.HORIZONTAL;
+import static java.awt.GridBagConstraints.WEST;
+import static ui.gui.widgets.UIUtils.alert;
+
+/**
+ * A dialog that presents user with cert info, revocation reason, and revocation time.
+ * +----------------------------+
+ * |Revoking: CN=xyz (Serial: 1)|
+ * |Reason: (Drop Down) |
+ * |Time: (ISO-8601 text) |
+ * | |
+ * | Revoke Cancel|
+ * +----------------------------+
+ */
+public class RevokeDialog extends JDialog {
+ /**
+ * ISO8601
+ */
+ private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
+
+ /**
+ * The incoming certificate.
+ */
+ private final Certificate crt;
+
+ /**
+ * The result.
+ */
+ private RevokedCertificate res;
+
+
+ /**
+ * Root pane
+ */
+ private JPanel contentPane;
+
+ /**
+ * OK button
+ */
+ private JButton buttonOK;
+
+ /**
+ * Cancel button
+ */
+ private JButton buttonCancel;
+
+ /**
+ * Reason
+ */
+ private JComboBox<String> comboBoxReason;
+
+ /**
+ * Subject (not editable)
+ */
+ private JTextField textFieldSubject;
+
+ /**
+ * Time
+ */
+ private JFormattedTextField formattedTextFieldTime;
+
+ /**
+ * EFFECTS: Init GUI with the given cert.
+ */
+ public RevokeDialog(Certificate crt) {
+ this.crt = crt;
+
+ contentPane = new JPanel();
+ contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.PAGE_AXIS));
+ contentPane.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
+ contentPane.add(renderForm());
+
+ contentPane.add(UIUtils.createActionsPane(buttonOK = new JButton("Revoke"),
+ buttonCancel = new JButton("Cancel")));
+ buttonOK.addActionListener(this::onOK);
+ buttonCancel.addActionListener(this::onCancel);
+
+ setContentPane(contentPane);
+ setModal(true);
+ getRootPane().setDefaultButton(buttonOK);
+ setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+
+ setTitle("Revoke certificate");
+
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ onCancel(null);
+ }
+ });
+
+ contentPane.registerKeyboardAction(this::onCancel,
+ KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
+ JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+ }
+
+ /**
+ * EFFECTS: Init GUI.
+ * MODIFIES: this
+ */
+ private JPanel renderForm() {
+ final JPanel panelForm = new JPanel();
+ panelForm.setLayout(new GridBagLayout());
+
+ panelForm.add(new JLabel("Revoking: "), new GCBuilder().anchor(WEST).build());
+ panelForm.add(new JLabel("Reason: "), new GCBuilder().gridY(1).anchor(WEST).build());
+ panelForm.add(new JLabel("Time: "), new GCBuilder().gridY(2).anchor(WEST).build());
+
+ textFieldSubject = new JTextField(String.format("%s (Serial: %d)",
+ crt.getCertificate().getSubject().toString(), crt.getCertificate().getSerialNumber().getLong()));
+ textFieldSubject.setEditable(false);
+ panelForm.add(textFieldSubject, new GCBuilder().gridX(1).anchor(WEST).fill(HORIZONTAL).build());
+
+ comboBoxReason = new JComboBox<>(Arrays.stream(Reason.values()).map(Enum::toString).toArray(String[]::new));
+ panelForm.add(comboBoxReason, new GCBuilder().gridXY(1, 1).anchor(WEST).fill(HORIZONTAL).build());
+
+ formattedTextFieldTime = new JFormattedTextField(DATE_FORMAT.toFormat());
+ formattedTextFieldTime.setText(ZonedDateTime.now().format(DATE_FORMAT));
+ panelForm.add(formattedTextFieldTime, new GCBuilder().gridXY(1, 2).anchor(WEST).fill(HORIZONTAL).build());
+
+ panelForm.add(new JPanel(), new GCBuilder().gridXY(1, 3).expandXY().fill(HORIZONTAL).build());
+ return panelForm;
+ }
+
+ /**
+ * EFFECTS: Validate form, set result, and close dialog.
+ * Time must be a valid ISO-8601 string with offset, and it will be converted into UTC.
+ * Reason must be supported.
+ * MODIFIES: this
+ */
+ private void onOK(ActionEvent ev) {
+ try {
+ res = new RevokedCertificate(ASN1Object.TAG_SEQUENCE, null,
+ crt.getCertificate().getSerialNumber(),
+ new UtcTime(UtcTime.TAG, null,
+ ZonedDateTime.parse(formattedTextFieldTime.getText(), DATE_FORMAT)
+ .withZoneSameInstant(ZoneId.of("UTC"))),
+ Reason.valueOf(comboBoxReason.getSelectedItem().toString()));
+ dispose();
+ } catch (DateTimeParseException e) {
+ alert(rootPane, "Revoke certificate", "Invalid time: " + formattedTextFieldTime.getText()
+ + ". It must be a valid ISO8601 time with offset, like '1919-08-10T11:45:14+09:00'.");
+ } catch (IllegalArgumentException e) {
+ alert(rootPane, "Revoke certificate", "Invalid reason.");
+ }
+ }
+
+ /**
+ * EFFECTS: Clear the result and close dialog.
+ * MODIFIES: this
+ */
+ private void onCancel(ActionEvent ev) {
+ res = null;
+ dispose();
+ }
+
+ /**
+ * EFFECTS: Get result.
+ */
+ public RevokedCertificate getRes() {
+ return res;
+ }
+}