1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.cling.invoker.mvnenc;
20
21 import java.io.InterruptedIOException;
22 import java.util.ArrayList;
23
24 import org.apache.maven.api.cli.InvokerRequest;
25 import org.apache.maven.api.cli.mvnenc.EncryptOptions;
26 import org.apache.maven.cling.invoker.LookupInvoker;
27 import org.apache.maven.cling.invoker.ProtoLookup;
28 import org.apache.maven.cling.utils.CLIReportingUtils;
29 import org.jline.consoleui.prompt.ConsolePrompt;
30 import org.jline.reader.LineReaderBuilder;
31 import org.jline.reader.UserInterruptException;
32 import org.jline.terminal.Terminal;
33 import org.jline.utils.AttributedStyle;
34 import org.jline.utils.Colors;
35 import org.jline.utils.OSUtils;
36
37
38
39
40 public class EncryptInvoker extends LookupInvoker<EncryptContext> {
41
42 public EncryptInvoker(ProtoLookup protoLookup) {
43 super(protoLookup);
44 }
45
46 @Override
47 protected int execute(EncryptContext context) throws Exception {
48 return doExecute(context);
49 }
50
51 @Override
52 protected EncryptContext createContext(InvokerRequest invokerRequest) {
53 return new EncryptContext(invokerRequest);
54 }
55
56 @Override
57 protected void lookup(EncryptContext context) {
58 context.goals = context.lookup.lookupMap(Goal.class);
59 }
60
61 public static final int OK = 0;
62 public static final int ERROR = 1;
63 public static final int BAD_OPERATION = 2;
64 public static final int CANCELED = 3;
65
66 protected int doExecute(EncryptContext context) throws Exception {
67 try {
68 if (!context.interactive) {
69 context.terminal.writer().println("This tool works only in interactive mode!");
70 context.terminal
71 .writer()
72 .println("Tool purpose is to configure password management on developer workstations.");
73 context.terminal
74 .writer()
75 .println(
76 "Note: Generated configuration can be moved/copied to headless environments, if configured as such.");
77 return BAD_OPERATION;
78 }
79
80 context.header = new ArrayList<>();
81 context.style = new AttributedStyle();
82 context.addInHeader(
83 context.style.italic().bold().foreground(Colors.rgbColor("green")),
84 "Maven Encryption " + CLIReportingUtils.showVersionMinimal());
85 context.addInHeader("Tool for secure password management on workstations.");
86 context.addInHeader("This tool is part of Apache Maven 4 distribution.");
87 context.addInHeader("");
88
89 Thread executeThread = Thread.currentThread();
90 context.terminal.handle(Terminal.Signal.INT, signal -> executeThread.interrupt());
91 ConsolePrompt.UiConfig config;
92 if (context.terminal.getType().equals(Terminal.TYPE_DUMB)
93 || context.terminal.getType().equals(Terminal.TYPE_DUMB_COLOR)) {
94 context.terminal.writer().println(context.terminal.getName() + ": " + context.terminal.getType());
95 throw new IllegalStateException("Dumb terminal detected.\nThis tool requires real terminal to work!\n"
96 + "Note: On Windows Jansi or JNA library must be included in classpath.");
97 } else if (OSUtils.IS_WINDOWS) {
98 config = new ConsolePrompt.UiConfig(">", "( )", "(x)", "( )");
99 } else {
100 config = new ConsolePrompt.UiConfig("❯", "◯ ", "◉ ", "◯ ");
101 }
102 config.setCancellableFirstPrompt(true);
103
104 context.reader =
105 LineReaderBuilder.builder().terminal(context.terminal).build();
106 context.prompt = new ConsolePrompt(context.reader, context.terminal, config);
107
108 EncryptOptions options = (EncryptOptions) context.invokerRequest.options();
109 if (options.goals().isEmpty() || options.goals().get().size() != 1) {
110 return badGoalsErrorMessage("No goal or multiple goals specified, specify only one goal.", context);
111 }
112
113 String goalName = options.goals().get().get(0);
114 Goal goal = context.goals.get(goalName);
115
116 if (goal == null) {
117 return badGoalsErrorMessage("Unknown goal: " + goalName, context);
118 }
119
120 return goal.execute(context);
121 } catch (InterruptedException | InterruptedIOException | UserInterruptException e) {
122 context.terminal.writer().println("Goal canceled by user.");
123 return CANCELED;
124 } catch (Exception e) {
125 if (context.invokerRequest.options().showErrors().orElse(false)) {
126 context.terminal.writer().println(e.getMessage());
127 e.printStackTrace(context.terminal.writer());
128 } else {
129 context.terminal.writer().println(e.getMessage());
130 }
131 return ERROR;
132 } finally {
133 context.terminal.writer().flush();
134 }
135 }
136
137 protected int badGoalsErrorMessage(String message, EncryptContext context) {
138 context.terminal.writer().println(message);
139 context.terminal.writer().println("Supported goals are: " + String.join(", ", context.goals.keySet()));
140 context.terminal.writer().println("Use -h to display help.");
141 return BAD_OPERATION;
142 }
143 }