Skip to content

Commit e4191d6

Browse files
committed
Code improvements
Originally suggested by @realpixelcode in #56
1 parent 296fa57 commit e4191d6

File tree

7 files changed

+122
-211
lines changed

7 files changed

+122
-211
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ pom.xml.versionsBackup
2121
.idea/dictionaries
2222
.idea/**/libraries/
2323
*.iml
24+

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
[![License](https://img.shields.io/github/license/purejava/keepassxc-proxy-access.svg)](https://github.com/purejava/keepassxc-proxy-access/blob/master/LICENSE)
88
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate?hosted_button_id=XVX9ZM7WE4ANL)
99

10-
A Java library to access KeePassXC via its built-in proxy. Requires KeePassXC 2.6.0 or newer.
10+
A Java library to access KeePassXC via its build-in proxy. Requires KeePassXC 2.6.0 or newer.
1111

1212
# Dependency
1313
Add `keepassxc-proxy-access` as a dependency to your project.

src/main/java/org/keepassxc/Connection.java

Lines changed: 32 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public abstract class Connection implements AutoCloseable {
2727
private final PropertyChangeSupport support;
2828

2929
private TweetNaclFast.Box box;
30-
private Credentials credentials;
30+
private Optional<Credentials> credentials;
3131
private final String clientID;
3232
private static final int nonceLength = 24;
3333
private byte[] nonce;
@@ -87,6 +87,7 @@ public Connection() {
8787
new Random().nextBytes(array);
8888
clientID = b64encode(array);
8989
nonce = TweetNaclFast.randombytes(nonceLength);
90+
credentials = Optional.empty();
9091
support = new PropertyChangeSupport(this);
9192
scheduler = Executors.newSingleThreadScheduledExecutor();
9293
}
@@ -115,18 +116,18 @@ public void run() {
115116
if (!isSignal(response)) LOG.trace("Response added to queue: {}", response);
116117
queue.offer(response);
117118
errorCount = 0;
118-
continue;
119-
}
120-
errorCount++;
121-
if (errorCount > MAX_ERROR_COUNT) {
122-
LOG.info("Too much errors - stopping MessagePublisher");
123-
doStop();
124-
try {
125-
terminateConnection();
126-
} catch (IOException e) {
127-
LOG.error(e.toString(), e.getCause());
119+
} else {
120+
errorCount++;
121+
if (errorCount > MAX_ERROR_COUNT) {
122+
LOG.info("Too much errors - stopping MessagePublisher");
123+
doStop();
124+
try {
125+
terminateConnection();
126+
} catch (IOException e) {
127+
LOG.error(e.toString(), e.getCause());
128+
}
129+
reconnect();
128130
}
129-
reconnect();
130131
}
131132
}
132133
LOG.debug("MessagePublisher stopped");
@@ -269,13 +270,8 @@ private synchronized byte[] sendEncryptedMessage(Map<String, Object> msg) throws
269270
throw new IllegalStateException(NOT_CONNECTED);
270271
}
271272

272-
var publicKey = Optional.ofNullable(credentials).orElseThrow(
273-
() -> new IllegalStateException(KEYEXCHANGE_MISSING)
274-
).getServerPublicKey();
275-
276-
var keyPair = Optional.ofNullable(credentials).orElseThrow(
277-
() -> new IllegalStateException(KEYEXCHANGE_MISSING)
278-
).getOwnKeypair();
273+
var publicKey = credentials.orElseThrow(() -> new IllegalStateException(KEYEXCHANGE_MISSING)).getServerPublicKey();
274+
var keyPair = credentials.orElseThrow(() -> new IllegalStateException(KEYEXCHANGE_MISSING)).getOwnKeypair();
279275

280276
if (msg.containsKey("triggerUnlock") && msg.get("triggerUnlock").equals("true")) {
281277
msg.remove("triggerUnlock");
@@ -390,11 +386,11 @@ protected void changePublicKeys() throws IOException, KeepassProxyAccessExceptio
390386
var publicKey = b64decode(response.getString("publicKey").getBytes());
391387
box = new TweetNaclFast.Box(publicKey, keyPair.getSecretKey());
392388

393-
if (Optional.ofNullable(credentials).isEmpty()) {
394-
setCredentials(new Credentials());
389+
if (credentials.isEmpty()) {
390+
setCredentials(Optional.of(new Credentials()));
395391
}
396-
Optional.ofNullable(credentials).orElseThrow(() -> new IllegalStateException(MISSING_CLASS)).setOwnKeypair(keyPair);
397-
Optional.ofNullable(credentials).orElseThrow(() -> new IllegalStateException(MISSING_CLASS)).setServerPublicKey(publicKey);
392+
credentials.orElseThrow(() -> new IllegalStateException(MISSING_CLASS)).setOwnKeypair(keyPair);
393+
credentials.orElseThrow(() -> new IllegalStateException(MISSING_CLASS)).setServerPublicKey(publicKey);
398394
support.firePropertyChange("credentialsCreated", null, credentials);
399395

400396
}
@@ -408,8 +404,7 @@ protected void changePublicKeys() throws IOException, KeepassProxyAccessExceptio
408404
*/
409405
public void associate() throws IOException, KeepassProxyAccessException {
410406
var idKeyPair = TweetNaclFast.Box.keyPair();
411-
var keyPair = Optional.ofNullable(credentials).orElseThrow(
412-
() -> new IllegalStateException(KEYEXCHANGE_MISSING)).getOwnKeypair();
407+
var keyPair = credentials.orElseThrow(() -> new IllegalStateException(KEYEXCHANGE_MISSING)).getOwnKeypair();
413408

414409
// Send associate request
415410
var nonce = sendEncryptedMessage(Map.of(
@@ -432,12 +427,8 @@ public void associate() throws IOException, KeepassProxyAccessException {
432427
LOG.error(e.toString(), e.getCause());
433428
}
434429
assert response != null;
435-
Optional.ofNullable(credentials).orElseThrow(
436-
() -> new IllegalStateException(MISSING_CLASS)).setAssociateId(response.getString("id"));
437-
438-
Optional.ofNullable(credentials).orElseThrow(
439-
() -> new IllegalStateException(MISSING_CLASS)).setIdKeyPublicKey(idKeyPair.getPublicKey());
440-
430+
credentials.orElseThrow(() -> new IllegalStateException(MISSING_CLASS)).setAssociateId(response.getString("id"));
431+
credentials.orElseThrow(() -> new IllegalStateException(MISSING_CLASS)).setIdKeyPublicKey(idKeyPair.getPublicKey());
441432
support.firePropertyChange("associated", null, credentials);
442433
};
443434
scheduler.schedule(lookupResponse, RESPONSE_DELAY_MS, TimeUnit.MILLISECONDS);
@@ -451,36 +442,32 @@ public void associate() throws IOException, KeepassProxyAccessException {
451442
* @throws IOException Retrieving the hash failed due to technical reasons.
452443
* @throws KeepassProxyAccessException It was impossible to get the hash.
453444
*/
454-
public Optional<String> getDatabasehash() throws IOException, KeepassProxyAccessException {
445+
public String getDatabasehash() throws IOException, KeepassProxyAccessException {
455446
// Send get-databasehash request
456447
var nonce = sendEncryptedMessage(Map.of("action", Message.GET_DATABASE_HASH.action));
457448
var response = getEncryptedResponseAndDecrypt(Message.GET_DATABASE_HASH.action, nonce);
458449

459-
if (response.has("hash") && !response.getString("hash").isBlank()) {
460-
return Optional.of(response.getString("hash"));
461-
}
462-
463-
return Optional.empty();
450+
return response.getString("hash");
464451
}
465452

466453
/**
467454
* Request for receiving the database hash (SHA256) of the current active KeePassXC database.
468455
* Sent together with a request to unlock the KeePassXC database.
469456
*
470457
* @param triggerUnlock When true, the KeePassXC application is brought to the front and unlock is requested from the user.
471-
* @return The database hash of the current active KeePassXC database.
458+
* @return The database hash of the current active KeePassXC database. Empty if the database is locked.
472459
* @throws IOException Retrieving the hash failed due to technical reasons.
473460
* @throws KeepassProxyAccessException It was impossible to get the hash.
474461
*/
475-
public Optional<String> getDatabasehash(boolean triggerUnlock) throws IOException, KeepassProxyAccessException {
462+
public String getDatabasehash(boolean triggerUnlock) throws IOException, KeepassProxyAccessException {
476463
// Send get-databasehash request with triggerUnlock, if needed
477464
var map = new HashMap<String, Object>(); // Map.of can't be used here, because we need a mutable object
478465
map.put("action", Message.GET_DATABASE_HASH.action);
479466
map.put("triggerUnlock", Boolean.toString(triggerUnlock));
480467
var nonce = sendEncryptedMessage(map);
481468
var response = getEncryptedResponseAndDecrypt(Message.GET_DATABASE_HASH.action, nonce);
482469

483-
return Optional.ofNullable(response.getString("hash"));
470+
return response.getString("hash");
484471
}
485472

486473
/**
@@ -845,15 +832,15 @@ private JSONArray checkKeysList(List<Map<String, String>> list) throws KeepassPr
845832
}
846833

847834
// Getters and Setters
848-
public Optional<String> getIdKeyPairPublicKey() {
849-
return Optional.ofNullable(credentials).map(value -> b64encode(value.getIdKeyPublicKey()));
835+
public String getIdKeyPairPublicKey() {
836+
return credentials.map(value -> b64encode(value.getIdKeyPublicKey())).orElse("");
850837
}
851838

852-
public Optional<String> getAssociateId() {
853-
return Optional.ofNullable(this.credentials).flatMap(Credentials::getAssociateId);
839+
public String getAssociateId() {
840+
return credentials.map(Credentials::getAssociateId).orElse("");
854841
}
855842

856-
public void setCredentials(Credentials credentials) {
843+
public void setCredentials(Optional<Credentials> credentials) {
857844
this.credentials = credentials;
858845
}
859846

src/main/java/org/purejava/Credentials.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@ public class Credentials implements Serializable {
1515

1616
private byte[] serverPublicKey;
1717

18-
private transient String associateId;
18+
private transient Optional<String> associateId;
1919
private String aID;
2020

21-
private transient byte[] idKeyPublicKey;
21+
private transient Optional<byte[]> idKeyPublicKey;
2222
private byte[] idKeyPub;
2323

24+
public Credentials() {
25+
this.associateId = Optional.empty();
26+
this.idKeyPublicKey = Optional.empty();
27+
}
28+
2429
@Serial
2530
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
2631
ois.defaultReadObject();
@@ -33,7 +38,7 @@ private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IO
3338
@Serial
3439
private void writeObject(ObjectOutputStream oos) throws IOException {
3540
secretKey = ownKeypair.getSecretKey();
36-
aID = getAssociateId().orElse(null);
41+
aID = getAssociateId();
3742
idKeyPub = getIdKeyPublicKey();
3843
oos.defaultWriteObject();
3944
}
@@ -55,32 +60,27 @@ public void setServerPublicKey(byte[] serverPublicKey) {
5560
this.serverPublicKey = serverPublicKey;
5661
}
5762

58-
public Optional<String> getAssociateId() {
59-
if (associateId == null || associateId.isEmpty())
60-
return Optional.empty();
61-
62-
return Optional.of(associateId);
63+
public String getAssociateId() {
64+
return associateId.isEmpty() ? "" : associateId.get();
6365
}
6466

6567
public void setAssociateId(String associateId) {
6668
if (associateId.isEmpty()) {
67-
this.associateId = null;
68-
return;
69+
this.associateId = Optional.empty();
70+
} else {
71+
this.associateId = Optional.of(associateId);
6972
}
70-
71-
this.associateId = associateId;
7273
}
7374

7475
public byte[] getIdKeyPublicKey() {
75-
return Optional.ofNullable(idKeyPublicKey).isEmpty() ? new byte[]{} : idKeyPublicKey;
76+
return idKeyPublicKey.isEmpty() ? new byte[]{} : idKeyPublicKey.get();
7677
}
7778

7879
public void setIdKeyPublicKey(byte[] idKeyPublicKey) {
7980
if (idKeyPublicKey.length == 0) {
80-
this.idKeyPublicKey = null;
81-
return;
81+
this.idKeyPublicKey = Optional.empty();
82+
} else {
83+
this.idKeyPublicKey = Optional.of(idKeyPublicKey);
8284
}
83-
84-
this.idKeyPublicKey = idKeyPublicKey;
8585
}
8686
}

0 commit comments

Comments
 (0)