Skip to content

Commit 42b8ab7

Browse files
committed
Add manual list test for https hubs.
1 parent be7fdd0 commit 42b8ab7

File tree

9 files changed

+214
-28
lines changed

9 files changed

+214
-28
lines changed

hub/pom.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,24 @@
126126
<artifactId>testcontainers</artifactId>
127127
<scope>test</scope>
128128
</dependency>
129+
<dependency>
130+
<groupId>io.github.coffeelibs</groupId>
131+
<artifactId>tiny-oauth2-client</artifactId>
132+
<version>0.8.0</version>
133+
<scope>test</scope>
134+
</dependency>
135+
<dependency>
136+
<groupId>org.htmlunit</groupId>
137+
<artifactId>htmlunit</artifactId>
138+
<version>4.2.0</version>
139+
<scope>test</scope>
140+
<exclusions>
141+
<exclusion>
142+
<groupId>org.eclipse.jetty</groupId>
143+
<artifactId>*</artifactId>
144+
</exclusion>
145+
</exclusions>
146+
</dependency>
129147

130148
<!-- @Nullable annotation -->
131149
<dependency>
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright (c) 2025 shift7 GmbH. All rights reserved.
3+
*/
4+
5+
package cloud.katta.core;
6+
7+
import ch.cyberduck.core.Credentials;
8+
import ch.cyberduck.core.OAuthTokens;
9+
10+
import org.junit.jupiter.api.Assertions;
11+
import org.junit.jupiter.api.Disabled;
12+
import org.junit.jupiter.api.Test;
13+
14+
import java.net.ProxySelector;
15+
import java.net.URI;
16+
import java.net.http.HttpClient;
17+
import java.net.http.HttpResponse;
18+
import java.util.Date;
19+
import java.util.List;
20+
import java.util.UUID;
21+
22+
import cloud.katta.client.ApiException;
23+
import cloud.katta.client.api.StorageProfileResourceApi;
24+
import cloud.katta.client.api.VaultResourceApi;
25+
import cloud.katta.client.model.StorageProfileDto;
26+
import cloud.katta.client.model.VaultDto;
27+
import cloud.katta.crypto.UserKeys;
28+
import cloud.katta.model.StorageProfileDtoWrapper;
29+
import cloud.katta.protocols.hub.HubSession;
30+
import cloud.katta.testsetup.AbstractHubTest;
31+
import cloud.katta.testsetup.HubTestConfig;
32+
import cloud.katta.workflows.CreateVaultService;
33+
import cloud.katta.workflows.DeviceKeysServiceImpl;
34+
import cloud.katta.workflows.UserKeysServiceImpl;
35+
import com.fasterxml.jackson.databind.ObjectMapper;
36+
import io.github.coffeelibs.tinyoauth2client.TinyOAuth2;
37+
38+
public class ManualListTest extends AbstractHubTest {
39+
40+
@Test
41+
@Disabled("run manually")
42+
public void testManualListing() throws Exception {
43+
final String hubURL = "https://testing.katta.cloud/tamarind";
44+
final String keycloakAuthServerUrl = "https://testing.katta.cloud/kc/realms/tamarind";
45+
final String clientId = "cryptomator";
46+
final String username = System.getenv().get("username");
47+
final String accountKey = System.getenv().get("account_key");
48+
49+
final String storageProfileId = "45a3cd17-9955-4580-9e60-790d84f5785f";
50+
final String vaultName = "vault " + username + " " + new Date();
51+
final String vaultDescription = "fancy";
52+
53+
String initialAccessToken;
54+
try (var client = HttpClient.newBuilder()
55+
.followRedirects(HttpClient.Redirect.NORMAL)
56+
.proxy(ProxySelector.getDefault())
57+
.build()) {
58+
59+
final HttpResponse<String> authResponse = TinyOAuth2.client(clientId)
60+
.withTokenEndpoint(URI.create(keycloakAuthServerUrl + "/protocol/openid-connect/token"))
61+
.authorizationCodeGrant(URI.create(keycloakAuthServerUrl + "/protocol/openid-connect/auth"))
62+
.authorize(client, uri -> {
63+
System.out.println("Please login on " + uri);
64+
});
65+
66+
Assertions.assertEquals(200, authResponse.statusCode());
67+
initialAccessToken = new ObjectMapper().reader().readTree(authResponse.body()).get("access_token").asText();
68+
}
69+
70+
HubTestConfig.Setup config = new HubTestConfig.Setup().withUserConfig(
71+
new HubTestConfig.Setup.UserConfig(new Credentials(username, null).withOauth(new OAuthTokens(initialAccessToken, null, System.currentTimeMillis() + 300 * 1000, initialAccessToken)), accountKey)
72+
).withHubURL(hubURL);
73+
74+
75+
final HubSession hubSession = setupConnection(config);
76+
printVaults(hubSession);
77+
78+
79+
if(storageProfileId != null) {
80+
final VaultResourceApi vaults = new VaultResourceApi(hubSession.getClient());
81+
82+
System.out.println(vaults.apiVaultsAccessibleGet(null));
83+
List<StorageProfileDto> storageProfileDtos = new StorageProfileResourceApi(hubSession.getClient()).apiStorageprofileGet(false);
84+
for(StorageProfileDto storageProfileDto : storageProfileDtos) {
85+
System.out.println(storageProfileDto);
86+
}
87+
final UserKeys userKeys = new UserKeysServiceImpl(hubSession).getUserKeys(hubSession.getHost(), hubSession.getMe(),
88+
new DeviceKeysServiceImpl().getDeviceKeys(hubSession.getHost()));
89+
90+
final List<StorageProfileDto> storageProfiles = new StorageProfileResourceApi(hubSession.getClient()).apiStorageprofileGet(false);
91+
92+
final StorageProfileDtoWrapper storageProfileWrapper = storageProfiles.stream()
93+
.map(StorageProfileDtoWrapper::coerce)
94+
.filter(p -> p.getId().toString().equals(storageProfileId)).findFirst().get();
95+
final UUID vaultId = UUID.randomUUID();
96+
97+
new CreateVaultService(hubSession).createVault(userKeys, storageProfileWrapper, new CreateVaultService.CreateVaultModel(
98+
vaultId, vaultName, vaultDescription,
99+
storageProfileId, null, null, null, "eu-west-1", true, 3));
100+
101+
printVaults(hubSession);
102+
}
103+
104+
105+
}
106+
107+
private static void printVaults(HubSession hubSession) throws ApiException {
108+
List<VaultDto> vaultL = new VaultResourceApi(hubSession.getClient()).apiVaultsAccessibleGet(null);
109+
for(VaultDto vaultDto : vaultL) {
110+
System.out.println(vaultDto);
111+
}
112+
}
113+
114+
}

hub/src/test/java/cloud/katta/testsetup/AbstractHubTest.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.junit.jupiter.params.provider.Arguments;
2121

2222
import java.io.IOException;
23+
import java.net.URI;
2324
import java.nio.file.Files;
2425
import java.time.ZoneId;
2526
import java.time.ZonedDateTime;
@@ -70,8 +71,8 @@ public abstract class AbstractHubTest extends VaultTest {
7071
LOCAL_DOCKER_CONFIG = new HubTestConfig.Setup.DockerConfig("/docker-compose-minio-localhost-hub.yml", "/.local.env", "local", "admin", "admin", "top-secret");
7172
LOCAL = new HubTestConfig.Setup()
7273
.withHubURL("http://localhost:8280")
73-
.withUserConfig(new HubTestConfig.Setup.UserConfig("alice", "asd", staticSetupCode()))
74-
.withAdminConfig(new HubTestConfig.Setup.UserConfig("admin", "admin", staticSetupCode()))
74+
.withUserConfig(new HubTestConfig.Setup.UserConfig(new Credentials("alice", "asd"), staticSetupCode()))
75+
.withAdminConfig(new HubTestConfig.Setup.UserConfig(new Credentials("admin", "admin"), staticSetupCode()))
7576
.withDockerConfig(LOCAL_DOCKER_CONFIG);
7677
}
7778

@@ -88,8 +89,8 @@ public abstract class AbstractHubTest extends VaultTest {
8889
*/
8990
private static final HubTestConfig.Setup LOCAL_ATTENDED = new HubTestConfig.Setup()
9091
.withHubURL("http://localhost:8080")
91-
.withAdminConfig(new HubTestConfig.Setup.UserConfig("admin", "admin", staticSetupCode()))
92-
.withUserConfig(new HubTestConfig.Setup.UserConfig("alice", "asd", staticSetupCode()));
92+
.withAdminConfig(new HubTestConfig.Setup.UserConfig(new Credentials("admin", "admin"), staticSetupCode()))
93+
.withUserConfig(new HubTestConfig.Setup.UserConfig(new Credentials("alice", "asd"), staticSetupCode()));
9394
private static final Function<HubTestConfig.VaultSpec, Arguments> argumentAttendedLocalOnly = vs -> Arguments.of(Named.of(
9495
String.format("%s %s (Bucket %s)", vs.storageProfileName, LOCAL_ATTENDED.hubURL, vs.bucketName),
9596
new HubTestConfig(LOCAL_ATTENDED, vs)));
@@ -112,15 +113,15 @@ public abstract class AbstractHubTest extends VaultTest {
112113
HYBRID = new HubTestConfig.Setup()
113114
.withHubURL("http://localhost:8280")
114115
.withUserConfig(
115-
new HubTestConfig.Setup.UserConfig(
116+
new HubTestConfig.Setup.UserConfig(new Credentials(
116117
PROPERTIES.get("testing.katta.cloud.chipotle.user.name"),
117-
PROPERTIES.get("testing.katta.cloud.chipotle.user.password"),
118+
PROPERTIES.get("testing.katta.cloud.chipotle.user.password")),
118119
staticSetupCode())
119120
)
120121
.withAdminConfig(
121-
new HubTestConfig.Setup.UserConfig(
122+
new HubTestConfig.Setup.UserConfig(new Credentials(
122123
PROPERTIES.get("testing.katta.cloud.chipotle.admin.name"),
123-
PROPERTIES.get("testing.katta.cloud.chipotle.admin.password"),
124+
PROPERTIES.get("testing.katta.cloud.chipotle.admin.password")),
124125
staticSetupCode())
125126
)
126127
.withDockerConfig(HYBRID_DOCKER_CONFIG);
@@ -194,7 +195,16 @@ protected static HubSession setupConnection(final HubTestConfig.Setup setup) thr
194195
final DeviceSetupCallback proxy = deviceSetupCallback(setup);
195196
MockableDeviceSetupCallback.setProxy(proxy);
196197

197-
final Host hub = new HostParser(factory).get(setup.hubURL).withCredentials(new Credentials(setup.userConfig.username, setup.userConfig.password));
198+
final Scheme scheme = setup.hubURL.startsWith("https://") ? Scheme.https : Scheme.http;
199+
final Protocol profile = factory.find(p -> p.getScheme().equals(scheme) && p.getIdentifier().equals("hub") && p.isEnabled()).getFirst();
200+
factory.find(p -> p.getIdentifier().equals("hub") && !p.getScheme().equals(scheme) && p instanceof Profile).stream().forEach(p -> factory.unregister((Profile) p));
201+
assertNotNull(factory.forName("hub"));
202+
assertNotNull(factory.forName("s3"));
203+
final Host hub = new Host(profile).withCredentials(new Credentials(setup.userConfig.credentials).withOauth(new OAuthTokens(setup.userConfig.credentials.getOauth() != null ? setup.userConfig.credentials.getOauth() : OAuthTokens.EMPTY)));
204+
hub.setHostname(HostParser.parse(setup.hubURL).getHostname());
205+
hub.setDefaultPath(HostParser.parse(setup.hubURL).getDefaultPath());
206+
hub.setPort(URI.create(setup.hubURL).getPort() > 0 ? URI.create(setup.hubURL).getPort() : scheme.getPort());
207+
198208
final HubSession session = (HubSession) SessionFactory.create(hub, new DefaultX509TrustManager(), new DefaultX509KeyManager())
199209
.withRegistry(VaultRegistryFactory.get(new DisabledPasswordCallback()));
200210
final LoginConnectionService login = new LoginConnectionService(new DisabledLoginCallback(), new DisabledHostKeyCallback(),

hub/src/test/java/cloud/katta/testsetup/HubTestConfig.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
package cloud.katta.testsetup;
66

7+
import ch.cyberduck.core.Credentials;
8+
79
public class HubTestConfig {
810
public final Setup setup;
911
public final VaultSpec vault;
@@ -80,21 +82,18 @@ public DockerConfig(final String composeFile, final String envFile, final String
8082
}
8183

8284
public static class UserConfig {
83-
public final String username;
84-
public final String password;
8585
public final String setupCode;
86+
public final Credentials credentials;
8687

87-
public UserConfig(final String username, final String password, final String setupCode) {
88-
this.username = username;
89-
this.password = password;
88+
public UserConfig(final Credentials credentials, final String setupCode) {
9089
this.setupCode = setupCode;
90+
this.credentials = credentials;
9191
}
9292

9393
@Override
9494
public String toString() {
9595
final StringBuilder sb = new StringBuilder("HubTestSetupUserConfig{");
96-
sb.append("username='").append(username).append('\'');
97-
sb.append(", password='").append(password).append('\'');
96+
sb.append("credentials='").append(credentials).append('\'');
9897
sb.append(", setupCode='").append(setupCode).append('\'');
9998
sb.append('}');
10099
return sb.toString();

hub/src/test/java/cloud/katta/testsetup/HubTestUtilities.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class HubTestUtilities {
2929
public static ApiClient getAdminApiClient(final HubTestConfig.Setup setup) throws IOException, ApiException {
3030
final ConfigDto config = new ConfigResourceApi(new ApiClient().setBasePath(setup.hubURL)).apiConfigGet();
3131
final PasswordTokenRequest request = new PasswordTokenRequest(new ApacheHttpTransport(), new GsonFactory(), new GenericUrl(config.getKeycloakTokenEndpoint()),
32-
setup.adminConfig.username, setup.adminConfig.password)
32+
setup.adminConfig.credentials.getUsername(), setup.adminConfig.credentials.getPassword())
3333
.setClientAuthentication(new ClientParametersAuthentication(setup.clientId, null))
3434
.setRequestInitializer(new UserAgentHttpRequestInitializer(new PreferencesUseragentProvider()));
3535
final String adminAccessToken = request.executeUnparsed().parseAs(OAuth2AuthorizationService.PermissiveTokenResponse.class).toTokenResponse().getAccessToken();

hub/src/test/java/cloud/katta/workflows/UserKeysServiceImplIT.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,16 @@
44

55
package cloud.katta.workflows;
66

7+
import ch.cyberduck.core.Credentials;
78
import ch.cyberduck.core.PasswordStoreFactory;
9+
10+
import org.junit.jupiter.api.extension.ExtendWith;
11+
import org.junit.jupiter.params.ParameterizedTest;
12+
import org.junit.jupiter.params.provider.Arguments;
13+
import org.junit.jupiter.params.provider.MethodSource;
14+
15+
import java.util.stream.Stream;
16+
817
import cloud.katta.client.api.DeviceResourceApi;
918
import cloud.katta.client.api.UsersResourceApi;
1019
import cloud.katta.client.model.DeviceDto;
@@ -17,15 +26,10 @@
1726
import cloud.katta.testsetup.HubTestSetupDockerExtension;
1827
import cloud.katta.workflows.exceptions.SecurityFailure;
1928
import com.nimbusds.jose.JOSEException;
29+
2030
import static org.junit.Assert.assertNotEquals;
2131
import static org.junit.jupiter.api.Assertions.assertEquals;
2232
import static org.junit.jupiter.api.Assertions.assertThrows;
23-
import org.junit.jupiter.api.extension.ExtendWith;
24-
import org.junit.jupiter.params.ParameterizedTest;
25-
import org.junit.jupiter.params.provider.Arguments;
26-
import org.junit.jupiter.params.provider.MethodSource;
27-
28-
import java.util.stream.Stream;
2933

3034
@ExtendWith({HubTestSetupDockerExtension.Local.class})
3135
class UserKeysServiceImplIT extends AbstractHubTest {
@@ -60,7 +64,7 @@ public void testFailSetupNewDeviceWithAccountKeyForExistingUserKeys(final HubTes
6064
final HubSession hubSession = setupConnection(config.setup);
6165

6266
// Setting up new device w/ Account Key for existing user keys with erroneous setup code
63-
final SecurityFailure securityException = assertThrows(SecurityFailure.class, () -> new UserKeysServiceImpl(hubSession).getOrCreateUserKeys(hubSession.getHost(), hubSession.getMe(), DeviceKeys.create(), deviceSetupCallback(new HubTestConfig.Setup().withUserConfig(new HubTestConfig.Setup.UserConfig("alice", "wonderland", "in")))));
67+
final SecurityFailure securityException = assertThrows(SecurityFailure.class, () -> new UserKeysServiceImpl(hubSession).getOrCreateUserKeys(hubSession.getHost(), hubSession.getMe(), DeviceKeys.create(), deviceSetupCallback(new HubTestConfig.Setup().withUserConfig(new HubTestConfig.Setup.UserConfig(new Credentials("alice", "wonderland"), "in")))));
6468
assertEquals(JOSEException.class, securityException.getCause().getClass());
6569
assertEquals("checksum failed", securityException.getCause().getCause().getMessage());
6670
}
@@ -111,7 +115,7 @@ public void testSetupNewUserKeysAndAccountKey(final HubTestConfig config) throws
111115
new UsersResourceApi(hubSession.getClient()).apiUsersMeGet(true, false);
112116

113117
// setting up new user keys and account key
114-
final UserKeys userKeys = new UserKeysServiceImpl(hubSession).getOrCreateUserKeys(hubSession.getHost(), newMe, DeviceKeys.create(), deviceSetupCallback(new HubTestConfig.Setup().withUserConfig(new HubTestConfig.Setup.UserConfig("alice", "wonderland", "in"))));
118+
final UserKeys userKeys = new UserKeysServiceImpl(hubSession).getOrCreateUserKeys(hubSession.getHost(), newMe, DeviceKeys.create(), deviceSetupCallback(new HubTestConfig.Setup().withUserConfig(new HubTestConfig.Setup.UserConfig(new Credentials("alice", "wonderland"), "in"))));
115119

116120
assertNotEquals(expecteduserKeys, userKeys);
117121

hub/src/test/resources/Katta Server.cyberduckprofile renamed to hub/src/test/resources/Katta Server http.cyberduckprofile

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
<key>Schemes</key>
1818
<array>
1919
<string>http</string>
20-
<string>https</string>
21-
<string>katta</string>
2220
</array>
2321
<key>Hostname Configurable</key>
2422
<true/>
@@ -37,4 +35,4 @@
3735
<key>Username Configurable</key>
3836
<false/>
3937
</dict>
40-
</plist>
38+
</plist>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright (c) 2025 shift7 GmbH. All rights reserved.
4+
-->
5+
6+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
7+
<plist version="1.0">
8+
<dict>
9+
<key>Protocol</key>
10+
<string>hub</string>
11+
<key>Vendor</key>
12+
<string>Shift 7 GmbH</string>
13+
<key>Bundled</key>
14+
<true/>
15+
<key>Scheme</key>
16+
<string>https</string>
17+
<key>Schemes</key>
18+
<array>
19+
<string>https</string>
20+
</array>
21+
<key>Hostname Configurable</key>
22+
<true/>
23+
<key>Authorization</key>
24+
<string>PasswordGrant</string>
25+
<key>Scopes</key>
26+
<array>
27+
<string>openid</string>
28+
</array>
29+
<key>OAuth Redirect Url</key>
30+
<string>${oauth.handler.scheme}:oauth</string>
31+
<key>OAuth Client Secret</key>
32+
<string/>
33+
<key>Password Configurable</key>
34+
<false/>
35+
<key>Username Configurable</key>
36+
<false/>
37+
</dict>
38+
</plist>

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
<properties>
2121
<maven.compiler.source>8</maven.compiler.source>
2222
<maven.compiler.target>8</maven.compiler.target>
23+
<maven.compiler.testSource>21</maven.compiler.testSource>
24+
<maven.compiler.testTarget>21</maven.compiler.testTarget>
2325

2426
<junit.jupiter.version>5.13.4</junit.jupiter.version>
2527
<junit.platform.version>1.13.4</junit.platform.version>
@@ -71,6 +73,9 @@
7173
<source>${maven.compiler.source}</source>
7274
<target>${maven.compiler.target}</target>
7375
<release>${maven.compiler.target}</release>
76+
<testSource>${maven.compiler.testSource}</testSource>
77+
<testTarget>${maven.compiler.testTarget}</testTarget>
78+
<testRelease>${maven.compiler.testTarget}</testRelease>
7479
<annotationProcessorPaths>
7580
<path>
7681
<groupId>com.google.auto.service</groupId>

0 commit comments

Comments
 (0)