aboutsummaryrefslogtreecommitdiff
path: root/src/main/ui/tui/JCA.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/ui/tui/JCA.java')
-rw-r--r--src/main/ui/tui/JCA.java220
1 files changed, 220 insertions, 0 deletions
diff --git a/src/main/ui/tui/JCA.java b/src/main/ui/tui/JCA.java
new file mode 100644
index 0000000..c23d610
--- /dev/null
+++ b/src/main/ui/tui/JCA.java
@@ -0,0 +1,220 @@
+package ui.tui;
+
+import model.asn1.exceptions.InvalidDBException;
+import model.asn1.exceptions.ParseException;
+import model.ca.CertificationAuthority;
+import persistence.Decoder;
+import persistence.FS;
+import ui.Utils;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Scanner;
+
+/**
+ * Main program
+ */
+public class JCA {
+ /**
+ * Default db file (./data/ca.json)
+ */
+ private static final Path PATH_DEFAULT = Path.of("data", "ca.json");
+
+ /**
+ * Instances of the five screens;
+ */
+ private final UIHandler mainScreen;
+ private final UIHandler mgmtScreen;
+ private final UIHandler issueScreen;
+ private final UIHandler templatesScreen;
+ private final UIHandler templateSetScreen;
+ /**
+ * The CA
+ */
+ private CertificationAuthority ca;
+ /**
+ * The current screen.
+ */
+ private UIHandler screen;
+
+ /**
+ * There are unsaved changes.
+ */
+ private boolean unsaved = false;
+
+ /**
+ * EFFECTS: Init with main screen and empty CA. No private key and no CA cert.
+ * Throws {@link NoSuchAlgorithmException} when crypto issue happens.
+ */
+ public JCA() throws NoSuchAlgorithmException, InvalidKeySpecException {
+ this.mainScreen = new MainScreen(this);
+ this.mgmtScreen = new MgmtScreen(this);
+ this.issueScreen = new IssueScreen(this);
+ this.templatesScreen = new TemplatesScreen(this);
+ this.templateSetScreen = new TemplateSetScreen(this);
+
+ setScreen(Screen.MAIN);
+
+ this.ca = new CertificationAuthority();
+ }
+
+ /**
+ * EFFECT: Checks if the CA is installed or not (according to the desired state) and print if not matching. Returns
+ * true if matching.
+ */
+ public boolean checkCA(boolean requireInstalled) {
+ if (requireInstalled && ca.getCertificate() == null) {
+ System.out.println("No CA installed");
+ return false;
+ } else if (!requireInstalled && ca.getCertificate() != null) {
+ System.out.println("CA already installed");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * EFFECTS: Read PEM from stdin, matched the given tag.
+ * Throws {@link ParseException} if the input is incorrect.
+ */
+ public Byte[] handleInputPEM(String desiredTag) throws ParseException {
+ final Scanner scanner = new Scanner(System.in);
+ StringBuilder in = new StringBuilder();
+ while (true) {
+ final String line = scanner.nextLine();
+ in.append(line);
+ in.append("\n");
+ if (line.matches("-----END .*-----")) {
+ break;
+ }
+ }
+ return Utils.parsePEM(Utils.byteToByte(in.toString().getBytes(StandardCharsets.UTF_8)), desiredTag);
+ }
+
+ /**
+ * EFFECT: Set the current screen with optional args. Exit the program when mode is null.
+ * MODIFIES: this
+ */
+ public void setScreen(Screen mode, Object... args) {
+ if (mode == null) {
+ System.exit(0);
+ }
+ switch (mode) {
+ case MAIN:
+ this.screen = mainScreen;
+ break;
+ case MGMT:
+ this.screen = mgmtScreen;
+ break;
+ case ISSUE:
+ this.screen = issueScreen;
+ break;
+ case TEMPLATES:
+ this.screen = templatesScreen;
+ break;
+ case TEMPLATE_SET:
+ this.screen = templateSetScreen;
+ break;
+ }
+ screen.enter(args);
+ }
+
+ /**
+ * EFFECTS: Read the database file and replace all local states.
+ * MODIFIES: this
+ */
+ private void load() {
+ if (unsaved) {
+ System.out.println("Current database is not saved yet.");
+ return;
+ }
+ try {
+ this.ca = Decoder.decodeCA(FS.read(PATH_DEFAULT));
+ } catch (InvalidDBException | NoSuchAlgorithmException e) {
+ System.out.println(e.getMessage());
+ if (e.getCause() != null) {
+ System.out.println(e.getCause().getMessage());
+ e.getCause().printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * EFFECTS: Handle input line
+ * MODIFIES: this
+ */
+ private void handleLine(String... args) {
+ if (args[0].equals("log")) {
+ ca.getLogs().forEach(System.out::println);
+ return;
+ }
+ if ("help".equals(args[0])) {
+ screen.help();
+ System.out.println("log\tView audit logs");
+ System.out.println("load\tLoad database");
+ System.out.println("save\tSave database");
+ } else if ("commit".equals(args[0])) {
+ screen.commit();
+ } else if ("show".equals(args[0])) {
+ screen.show();
+ } else if ("exit".equals(args[0])) {
+ setScreen(screen.exit());
+ } else if ("save".equals(args[0])) {
+ save();
+ } else if ("load".equals(args[0])) {
+ load();
+ } else {
+ screen.command(args);
+ }
+ printPS1();
+ }
+
+ /**
+ * EFFECTS: Print the '*user@JCA PS1' line
+ */
+ private void printPS1() {
+ System.out.printf("%s%s@JCA %s ",
+ unsaved ? "*" : "",
+ ca.getUser(),
+ screen.getPS1());
+ }
+
+ /**
+ * EFFECTS: Save the DB
+ */
+ public void save() {
+ try {
+ FS.write(PATH_DEFAULT, Decoder.encodeCA(ca));
+ unsaved = false;
+ } catch (IOException e) {
+ System.out.println(e.getMessage());
+ }
+ }
+
+ /**
+ * EFFECTS: Run the program
+ */
+ public void run() {
+ printPS1();
+ final Scanner scanner = new Scanner(System.in);
+ while (true) {
+ String[] args = scanner.nextLine().split(" ");
+ if (args.length <= 0 || args[0].isBlank()) {
+ printPS1();
+ continue;
+ }
+ handleLine(args);
+ }
+ }
+
+ public void setUnsaved(boolean unsaved) {
+ this.unsaved = unsaved;
+ }
+
+ public CertificationAuthority getCa() {
+ return ca;
+ }
+}