Skip to content

Commit 568b52c

Browse files
authored
Merge pull request #53 from /issues/36-fix-failing-user-keys-recovery
Fix failing user keys recovery
2 parents c2fac76 + a391640 commit 568b52c

File tree

5 files changed

+72
-2
lines changed

5 files changed

+72
-2
lines changed

hub/src/main/java/ch/iterate/hub/core/FirstLoginDeviceSetupCallback.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package ch.iterate.hub.core;
66

77
import ch.cyberduck.core.Host;
8+
import ch.cyberduck.core.UUIDRandomStringService;
89
import ch.cyberduck.core.exception.ConnectionCanceledException;
910
import ch.cyberduck.core.exception.LoginCanceledException;
1011

@@ -29,6 +30,15 @@ public interface FirstLoginDeviceSetupCallback {
2930
*/
3031
AccountKeyAndDeviceName askForAccountKeyAndDeviceName(Host bookmark, String initialDeviceName) throws ConnectionCanceledException;
3132

33+
/**
34+
* Generate initial account key
35+
*
36+
* @return Random UUID
37+
*/
38+
default String generateAccountKey() {
39+
return new UUIDRandomStringService().random();
40+
}
41+
3242
FirstLoginDeviceSetupCallback disabled = new FirstLoginDeviceSetupCallback() {
3343
@Override
3444
public String displayAccountKeyAndAskDeviceName(final Host bookmark, final AccountKeyAndDeviceName accountKeyAndDeviceName) throws ConnectionCanceledException {

hub/src/main/java/ch/iterate/hub/workflows/UserKeysServiceImpl.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package ch.iterate.hub.workflows;
66

77
import ch.cyberduck.core.Host;
8-
import ch.cyberduck.core.UUIDRandomStringService;
98
import ch.cyberduck.core.exception.ConnectionCanceledException;
109
import ch.cyberduck.core.exception.LocalAccessDeniedException;
1110

@@ -119,7 +118,7 @@ else if(userKeysInHub) {
119118
log.info("(3) Setting up new user keys and setupCode.");
120119

121120
log.info("(3.1) generate and display new Account Key");
122-
final String setupCode = new UUIDRandomStringService().random();
121+
final String setupCode = prompt.generateAccountKey();
123122
log.info("With setupCode={}", setupCode);
124123

125124
final String deviceName = prompt.displayAccountKeyAndAskDeviceName(host,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package ch.iterate.hub.core;
2+
3+
import ch.cyberduck.core.AlphanumericRandomStringService;
4+
5+
import org.junit.jupiter.api.TestInstance;
6+
import org.junit.jupiter.api.extension.ExtendWith;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.Arguments;
9+
import org.junit.jupiter.params.provider.MethodSource;
10+
11+
import java.security.InvalidKeyException;
12+
import java.util.stream.Stream;
13+
14+
import ch.iterate.hub.client.api.UsersResourceApi;
15+
import ch.iterate.hub.client.model.UserDto;
16+
import ch.iterate.hub.crypto.UserKeys;
17+
import ch.iterate.hub.protocols.hub.HubSession;
18+
import ch.iterate.hub.testsetup.AbstractHubTest;
19+
import ch.iterate.hub.testsetup.docker_setup.UnattendedLocalOnly;
20+
import ch.iterate.hub.testsetup.model.HubTestConfig;
21+
import com.nimbusds.jose.JOSEException;
22+
23+
import static ch.iterate.hub.testsetup.HubTestSetupConfigs.minioSTSUnattendedLocalOnly;
24+
import static ch.iterate.hub.testsetup.HubTestUtilities.setupForUser;
25+
import static org.junit.Assert.assertNotNull;
26+
import static org.junit.jupiter.api.Assertions.assertThrows;
27+
import static org.junit.jupiter.api.Assertions.assertTrue;
28+
29+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
30+
@ExtendWith({UnattendedLocalOnly.class})
31+
public class UserKeysRecoveryTest extends AbstractHubTest {
32+
33+
private Stream<Arguments> arguments() {
34+
return Stream.of(minioSTSUnattendedLocalOnly);
35+
}
36+
37+
@ParameterizedTest
38+
@MethodSource("arguments")
39+
public void firstLoginAndUserKeyRecovery(final HubTestConfig hubTestConfig) throws Exception {
40+
final HubSession hubSession = setupForUser(hubTestConfig.hubTestSetupConfig, hubTestConfig.hubTestSetupConfig.USER_001());
41+
final UsersResourceApi usersApi = new UsersResourceApi(hubSession.getClient());
42+
final UserDto me = usersApi.apiUsersMeGet(true);
43+
44+
final JOSEException exception = assertThrows(JOSEException.class, () -> UserKeys.recover(me.getEcdhPublicKey(), me.getEcdsaPublicKey(), me.getPrivateKey(),
45+
new AlphanumericRandomStringService().random()));
46+
assertTrue(exception.getCause() instanceof InvalidKeyException);
47+
48+
assertNotNull(UserKeys.recover(me.getEcdhPublicKey(), me.getEcdsaPublicKey(), me.getPrivateKey(),
49+
hubTestConfig.hubTestSetupConfig.USER_001().setupCode));
50+
}
51+
}

hub/src/test/java/ch/iterate/hub/core/util/MockableFirstLoginDeviceSetupCallback.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,9 @@ public String displayAccountKeyAndAskDeviceName(final Host bookmark, final Accou
2626
public AccountKeyAndDeviceName askForAccountKeyAndDeviceName(final Host bookmark, final String initialDeviceName) throws ConnectionCanceledException {
2727
return proxy.askForAccountKeyAndDeviceName(bookmark, initialDeviceName);
2828
}
29+
30+
@Override
31+
public String generateAccountKey() {
32+
return proxy.generateAccountKey();
33+
}
2934
}

hub/src/test/java/ch/iterate/hub/testsetup/HubTestUtilities.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ public AccountKeyAndDeviceName askForAccountKeyAndDeviceName(final Host bookmark
130130
return new AccountKeyAndDeviceName().withAccountKey(setupCode).withDeviceName(String.format("firstLoginMockSetup %s", DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL)
131131
.format(ZonedDateTime.now(ZoneId.of("Europe/Zurich")))));
132132
}
133+
134+
@Override
135+
public String generateAccountKey() {
136+
return setupCode;
137+
}
133138
};
134139
MockableFirstLoginDeviceSetupCallback.setProxy(proxy);
135140

0 commit comments

Comments
 (0)