-
Notifications
You must be signed in to change notification settings - Fork 19
/
CliUI.java
283 lines (237 loc) · 10.1 KB
/
CliUI.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
package digital.slovensko.autogram.ui.cli;
import static digital.slovensko.autogram.util.DSSUtils.parseCN;
import java.io.File;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import digital.slovensko.autogram.Main;
import digital.slovensko.autogram.core.Autogram;
import digital.slovensko.autogram.core.Batch;
import digital.slovensko.autogram.core.SigningJob;
import digital.slovensko.autogram.core.SigningKey;
import digital.slovensko.autogram.core.Updater;
import digital.slovensko.autogram.core.ValidationReports;
import digital.slovensko.autogram.core.errors.*;
import digital.slovensko.autogram.core.visualization.Visualization;
import digital.slovensko.autogram.drivers.TokenDriver;
import digital.slovensko.autogram.ui.BatchUiResult;
import digital.slovensko.autogram.ui.UI;
import digital.slovensko.autogram.ui.gui.IgnorableException;
import eu.europa.esig.dss.token.DSSPrivateKeyEntry;
public class CliUI implements UI {
private final CliSettings settings;
SigningKey activeKey;
int nJobsSigned = 1;
int nJobsTotal = 0;
public CliUI(CliSettings settings) {
this.settings = settings;
}
@Override
public void startSigning(SigningJob job, Autogram autogram) {
if (activeKey == null) {
autogram.pickSigningKeyAndThen(key -> {
activeKey = key;
sign(job, autogram);
});
} else {
sign(job, autogram);
}
}
private void sign(SigningJob job, Autogram autogram) {
System.out.println("Starting signing file \"%s\" [%d/%d]".formatted(job.getDocument().getName(), nJobsSigned++,
nJobsTotal));
autogram.sign(job, activeKey);
}
public void setJobsCount(int nJobsTotal) {
this.nJobsTotal = nJobsTotal;
}
@Override
public void startBatch(Batch batch, Autogram autogram, Consumer<SigningKey> callback) {
// TODO Auto-generated method stub
}
@Override
public void cancelBatch(Batch batch) {
// TODO Auto-generated method stub
}
@Override
public void pickTokenDriverAndThen(List<TokenDriver> drivers, Consumer<TokenDriver> callback) {
TokenDriver pickedDriver;
if (drivers.isEmpty()) {
showError(new NoDriversDetectedException());
return;
} else if (drivers.size() == 1) {
pickedDriver = drivers.get(0);
} else if (settings.getDefaultDriver() != null) {
var driver = drivers.stream().filter(d -> d.getShortname().equals(settings.getDefaultDriver())).findFirst();
if (driver.isEmpty())
throw new NoDriversDetectedException();
pickedDriver = driver.get();
} else {
var i = new AtomicInteger(1);
System.out.println("Pick driver:");
drivers.forEach(driver -> {
System.out.print("[" + i + "] ");
System.out.println(driver.getName());
i.addAndGet(1);
});
pickedDriver = drivers.get(CliUtils.readInteger() - 1);
}
callback.accept(pickedDriver);
}
@Override
public void pickKeyAndThen(List<DSSPrivateKeyEntry> keys, TokenDriver driver, Consumer<DSSPrivateKeyEntry> callback) {
if (keys.isEmpty()) {
showError(new NoKeysDetectedException(driver.getNoKeysHelperText()));
return;
}
if (keys.size() == 1) {
callback.accept(keys.get(0));
return;
}
System.out.println("Pick Key:");
var i = 1;
for (var key : keys) {
var keyText = parseCN(key.getCertificate().getSubject().getRFC2253());
if (!key.getCertificate().isValidOn(new java.util.Date()))
keyText += " (expired certificate)";
System.out.println("[" + i++ + "] " + keyText);
}
var pickedKey = keys.get(CliUtils.readInteger() - 1);
callback.accept(pickedKey);
}
@Override
public void onWorkThreadDo(Runnable callback) {
callback.run(); // no threads
}
@Override
public void onUIThreadDo(Runnable callback) {
callback.run(); // no threads
}
@Override
public void onSigningSuccess(SigningJob job) {
}
@Override
public void onSigningFailed(AutogramException e, SigningJob job) {
throw e;
}
@Override
public void onSigningFailed(AutogramException e) {
throw e;
}
@Override
public void onDocumentBatchSaved(BatchUiResult result) {
}
@Override
public void onDocumentSaved(File file) {
var directory = file.getParent() != null ? " in \"%s\"".formatted(file.getParent()) : "";
System.out
.println("File successfully signed. Signed file saved as \"%s\"".formatted(file.getName()) + directory);
}
@Override
public void onPickSigningKeyFailed(AutogramException e) {
showError(e);
}
@Override
public void onUpdateAvailable() {
System.out.println("Nová verzia");
System.out.println(String.format(
"Je dostupná nová verzia a odporúčame stiahnuť aktualizáciu. Najnovšiu verziu si možete vždy stiahnuť na %s.",
Updater.LATEST_RELEASE_URL));
}
@Override
public void onAboutInfo() {
System.out.println(
"""
O projekte Autogram
Autogram je jednoduchý nástroj na podpisovanie podľa európskeho nariadenia eIDAS, slovenských zákonov a štandardov. Môžete ho používať komerčne aj nekomerčne a úplne zadarmo.
Autori a sponzori
Autormi tohto projektu sú Jakub Ďuraš, Slovensko.Digital, CRYSTAL CONSULTING, s.r.o, Solver IT s.r.o. a ďalší spoluautori.
Licencia a zdrojové kódy
Tento softvér pôvodne vychádza projektu z Octosign White Label od Jakuba Ďuraša, ktorý je licencovaný pod MIT licenciou. So súhlasom autora je táto verzia distribuovaná pod licenciou EUPL v1.2.
Zdrojové kódy sú dostupné na https://github.com/slovensko-digital/autogram.""");
System.out.println(String.format("Verzia: %s", Main.getVersionString()));
}
@Override
public void onPDFAComplianceCheckFailed(SigningJob job) {
throw new PDFAComplianceException();
}
@Override
public void showVisualization(Visualization visualization, Autogram autogram) {
}
@Override
public void onSignatureValidationCompleted(ValidationReports reports) {
}
@Override
public void onSignatureCheckCompleted(ValidationReports reports) {
}
public void showIgnorableExceptionDialog(IgnorableException exception) {
throw exception;
}
public static String parseError(AutogramException e) {
if (e instanceof FunctionCanceledException) {
return "No security code entered";
} else if (e instanceof InitializationFailedException) {
return "Unable to read card";
} else if (e instanceof NoDriversDetectedException) {
return "No available drivers found";
} else if (e instanceof NoKeysDetectedException) {
return "No signing keys found";
} else if (e instanceof PDFAComplianceException) {
return "Document is not PDF/A compliant";
} else if (e instanceof PINIncorrectException) {
return "Incorrect security code";
} else if (e instanceof PINLockedException) {
return "PIN is blocked";
} else if (e instanceof SigningCanceledByUserException) {
return "Signing canceled by user";
} else if (e instanceof SigningWithExpiredCertificateException) {
return "Signing with expired certificate";
} else if (e instanceof TokenNotRecognizedException) {
return "Token not recognized";
} else if (e instanceof TokenRemovedException) {
return "Token removed";
} else if (e instanceof TargetAlreadyExistsException) {
return "Target already exists";
} else if (e instanceof SourceAndTargetTypeMismatchException) {
return "Source and target type mismatch (file / directory)";
} else if (e instanceof SourceDoesNotExistException) {
return "Source does not exist";
} else if (e instanceof SourceNotDefindedException) {
return "Source not defined";
} else if (e instanceof UnableToCreateDirectoryException) {
return "Unable to create directory";
} else if (e instanceof TokenDriverDoesNotExistException) {
return "Token driver does not exist";
} else if (e instanceof TargetDirectoryDoesNotExistException) {
return "Target directory does not exist";
} else if (e instanceof SlotIndexIsNotANumberException) {
return "Slot ID is not a number";
} else if (e instanceof PDFSignatureLevelIsNotValidException) {
return "PDF signature level is not valid";
} else if (e instanceof TsaServerMisconfiguredException) {
return "TSA server refused to add timestamp. Check TSA server configuration.";
} else if (e instanceof SlotIndexOutOfRangeException) {
return "Provided slot index is out of range for chosen driver.";
} else if (e instanceof PkcsEidWindowsDllException) {
return "PKCS library problem. Microsoft Visual C++ 2015 Redistributable probably needs to be installed.";
} else {
e.printStackTrace();
return "Unknown error occurred";
}
}
@Override
public void showError(AutogramException e) {
System.err.println(parseError(e));
}
@Override
public char[] getKeystorePassword() {
return System.console().readPassword("Enter keystore password (hidden): ");
}
public char[] getContextSpecificPassword() {
return System.console().readPassword("Enter key password (hidden): ");
}
@Override
public void updateBatch() {
// TODO: no usage for this in CLI UI
}
}