Skip to content

Commit d29def7

Browse files
committed
feat: STS client SQL store implementation
1 parent 7e0e0f5 commit d29def7

File tree

25 files changed

+1360
-203
lines changed

25 files changed

+1360
-203
lines changed

extensions/common/iam/identity-trust/identity-trust-sts/identity-trust-sts-api/src/test/java/org/eclipse/edc/api/iam/identitytrust/sts/controller/SecureServiceTokenApiControllerTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ void token() {
6363
.name("Name")
6464
.secretAlias(clientKeyAlias)
6565
.privateKeyAlias(privateKeyAlias)
66+
.publicKeyReference("publicKeyReference")
6667
.did(did)
6768
.build();
6869

extensions/common/iam/identity-trust/identity-trust-sts/identity-trust-sts-client-configuration/src/test/java/org/eclipse/edc/iam/identitytrust/sts/client/configuration/StsClientConfigurationExtensionTest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import static org.eclipse.edc.iam.identitytrust.sts.client.configuration.StsClientConfigurationExtension.CLIENT_ID;
3333
import static org.eclipse.edc.iam.identitytrust.sts.client.configuration.StsClientConfigurationExtension.CLIENT_NAME;
3434
import static org.eclipse.edc.iam.identitytrust.sts.client.configuration.StsClientConfigurationExtension.CLIENT_PRIVATE_KEY_ALIAS;
35+
import static org.eclipse.edc.iam.identitytrust.sts.client.configuration.StsClientConfigurationExtension.CLIENT_PUBLIC_KEY_REFERENCE;
3536
import static org.eclipse.edc.iam.identitytrust.sts.client.configuration.StsClientConfigurationExtension.CLIENT_SECRET_ALIAS;
3637
import static org.eclipse.edc.iam.identitytrust.sts.client.configuration.StsClientConfigurationExtension.CONFIG_PREFIX;
3738
import static org.eclipse.edc.iam.identitytrust.sts.client.configuration.StsClientConfigurationExtension.ID;
@@ -65,6 +66,7 @@ void initialize_withClient(ServiceExtensionContext context, StsClientConfigurati
6566
.privateKeyAlias("pAlias")
6667
.secretAlias("sAlias")
6768
.did("did:example:subject")
69+
.publicKeyReference("publicReference")
6870
.build();
6971
var clientAlias = "client";
7072
var config = ConfigFactory.fromMap(clientConfig(client, clientAlias));
@@ -74,7 +76,9 @@ void initialize_withClient(ServiceExtensionContext context, StsClientConfigurati
7476
var capture = ArgumentCaptor.forClass(StsClient.class);
7577
verify(clientStore).create(capture.capture());
7678

77-
assertThat(capture.getValue()).usingRecursiveComparison().isEqualTo(client);
79+
assertThat(capture.getValue()).usingRecursiveComparison()
80+
.ignoringFields("createdAt")
81+
.isEqualTo(client);
7882
}
7983

8084
private Map<String, String> clientConfig(StsClient client, String clientAlias) {
@@ -84,7 +88,8 @@ private Map<String, String> clientConfig(StsClient client, String clientAlias) {
8488
clientAlias + "." + CLIENT_ID, client.getClientId(),
8589
clientAlias + "." + CLIENT_SECRET_ALIAS, client.getSecretAlias(),
8690
clientAlias + "." + CLIENT_DID, client.getDid(),
87-
clientAlias + "." + CLIENT_PRIVATE_KEY_ALIAS, client.getPrivateKeyAlias()
91+
clientAlias + "." + CLIENT_PRIVATE_KEY_ALIAS, client.getPrivateKeyAlias(),
92+
clientAlias + "." + CLIENT_PUBLIC_KEY_REFERENCE, client.getPublicKeyReference()
8893
);
8994
}
9095

extensions/common/iam/identity-trust/identity-trust-sts/identity-trust-sts-core/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ dependencies {
1111
implementation(project(":spi:common:keys-spi"))
1212
implementation(project(":extensions:common:iam:identity-trust:identity-trust-sts:identity-trust-sts-embedded"))
1313
implementation(project(":core:common:token-core"))
14+
implementation(project(":core:common:lib:store-lib"))
1415

1516
testImplementation(testFixtures(project(":spi:common:identity-trust-sts-spi")))
1617
testImplementation(project(":core:common:lib:boot-lib"))
1718
testImplementation(project(":core:common:lib:crypto-common-lib"))
1819
testImplementation(project(":core:common:lib:keys-lib"))
1920
testImplementation(project(":core:common:junit"))
21+
testImplementation(project(":core:common:lib:query-lib"))
2022
testImplementation(libs.nimbus.jwt)
2123
}

extensions/common/iam/identity-trust/identity-trust-sts/identity-trust-sts-core/src/main/java/org/eclipse/edc/iam/identitytrust/sts/defaults/StsDefaultStoresExtension.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,26 @@
1717
import org.eclipse.edc.iam.identitytrust.sts.defaults.store.InMemoryStsClientStore;
1818
import org.eclipse.edc.iam.identitytrust.sts.spi.store.StsClientStore;
1919
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
20+
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
2021
import org.eclipse.edc.runtime.metamodel.annotation.Provider;
22+
import org.eclipse.edc.spi.query.CriterionOperatorRegistry;
2123
import org.eclipse.edc.spi.system.ServiceExtension;
2224

2325
@Extension(StsDefaultStoresExtension.NAME)
2426
public class StsDefaultStoresExtension implements ServiceExtension {
2527

2628
public static final String NAME = "Secure Token Service Default Stores";
2729

30+
@Inject
31+
private CriterionOperatorRegistry criterionOperatorRegistry;
32+
2833
@Override
2934
public String name() {
3035
return NAME;
3136
}
3237

3338
@Provider(isDefault = true)
3439
public StsClientStore clientStore() {
35-
return new InMemoryStsClientStore();
40+
return new InMemoryStsClientStore(criterionOperatorRegistry);
3641
}
3742
}

extensions/common/iam/identity-trust/identity-trust-sts/identity-trust-sts-core/src/main/java/org/eclipse/edc/iam/identitytrust/sts/defaults/store/InMemoryStsClientStore.java

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,17 @@
1616

1717
import org.eclipse.edc.iam.identitytrust.sts.spi.model.StsClient;
1818
import org.eclipse.edc.iam.identitytrust.sts.spi.store.StsClientStore;
19+
import org.eclipse.edc.spi.query.CriterionOperatorRegistry;
20+
import org.eclipse.edc.spi.query.QueryResolver;
21+
import org.eclipse.edc.spi.query.QuerySpec;
1922
import org.eclipse.edc.spi.result.StoreResult;
23+
import org.eclipse.edc.store.ReflectionBasedQueryResolver;
24+
import org.jetbrains.annotations.NotNull;
2025

2126
import java.util.Map;
2227
import java.util.Optional;
2328
import java.util.concurrent.ConcurrentHashMap;
29+
import java.util.stream.Stream;
2430

2531
import static java.lang.String.format;
2632

@@ -29,19 +35,54 @@
2935
*/
3036
public class InMemoryStsClientStore implements StsClientStore {
3137

38+
// we store it by clientId
3239
private final Map<String, StsClient> clients = new ConcurrentHashMap<>();
40+
private final QueryResolver<StsClient> queryResolver;
41+
42+
43+
public InMemoryStsClientStore(CriterionOperatorRegistry criterionOperatorRegistry) {
44+
queryResolver = new ReflectionBasedQueryResolver<>(StsClient.class, criterionOperatorRegistry);
45+
}
3346

3447
@Override
3548
public StoreResult<StsClient> create(StsClient client) {
3649
return Optional.ofNullable(clients.putIfAbsent(client.getClientId(), client))
37-
.map(old -> StoreResult.<StsClient>alreadyExists(format("Client with id %s already exists", client.getClientId())))
50+
.map(old -> StoreResult.<StsClient>alreadyExists(format(CLIENT_EXISTS_TEMPLATE, client.getClientId())))
3851
.orElseGet(() -> StoreResult.success(client));
3952
}
4053

4154
@Override
42-
public StoreResult<StsClient> findByClientId(String id) {
43-
return Optional.ofNullable(clients.get(id))
55+
public StoreResult<Void> update(StsClient stsClient) {
56+
var prev = clients.replace(stsClient.getClientId(), stsClient);
57+
return Optional.ofNullable(prev)
58+
.map(a -> StoreResult.<Void>success())
59+
.orElse(StoreResult.notFound(format(CLIENT_NOT_FOUND_BY_ID_TEMPLATE, stsClient.getId())));
60+
}
61+
62+
@Override
63+
public @NotNull Stream<StsClient> findAll(QuerySpec spec) {
64+
return queryResolver.query(clients.values().stream(), spec);
65+
}
66+
67+
@Override
68+
public StoreResult<StsClient> findById(String id) {
69+
return clients.values().stream()
70+
.filter(client -> client.getId().equals(id))
71+
.findFirst()
72+
.map(StoreResult::success)
73+
.orElseGet(() -> StoreResult.notFound(format(CLIENT_NOT_FOUND_BY_ID_TEMPLATE, id)));
74+
}
75+
76+
@Override
77+
public StoreResult<StsClient> findByClientId(String clientId) {
78+
return Optional.ofNullable(clients.get(clientId))
4479
.map(StoreResult::success)
45-
.orElseGet(() -> StoreResult.notFound(format("Client with id %s not found.", id)));
80+
.orElseGet(() -> StoreResult.notFound(format(CLIENT_NOT_FOUND_BY_CLIENT_ID_TEMPLATE, clientId)));
81+
}
82+
83+
@Override
84+
public StoreResult<StsClient> deleteById(String id) {
85+
return findById(id)
86+
.onSuccess(client -> clients.remove(client.getClientId()));
4687
}
4788
}

extensions/common/iam/identity-trust/identity-trust-sts/identity-trust-sts-core/src/test/java/org/eclipse/edc/iam/identitytrust/sts/defaults/StsClientTokenIssuanceIntegrationTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.eclipse.edc.keys.keyparsers.PemParser;
3030
import org.eclipse.edc.keys.spi.KeyParserRegistry;
3131
import org.eclipse.edc.keys.spi.PrivateKeyResolver;
32+
import org.eclipse.edc.query.CriterionOperatorRegistryImpl;
3233
import org.eclipse.edc.security.token.jwt.DefaultJwsSignerProvider;
3334
import org.eclipse.edc.spi.security.Vault;
3435
import org.eclipse.edc.token.JwtGenerationService;
@@ -56,7 +57,7 @@
5657
@ComponentTest
5758
public class StsClientTokenIssuanceIntegrationTest {
5859

59-
private final InMemoryStsClientStore clientStore = new InMemoryStsClientStore();
60+
private final InMemoryStsClientStore clientStore = new InMemoryStsClientStore(CriterionOperatorRegistryImpl.ofDefaults());
6061
private final Vault vault = new InMemoryVault(mock());
6162
private final KeyParserRegistry keyParserRegistry = new KeyParserRegistryImpl();
6263
private StsClientServiceImpl clientService;

extensions/common/iam/identity-trust/identity-trust-sts/identity-trust-sts-core/src/test/java/org/eclipse/edc/iam/identitytrust/sts/defaults/store/InMemoryStsClientStoreTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import org.eclipse.edc.iam.identitytrust.sts.spi.store.StsClientStore;
1818
import org.eclipse.edc.iam.identitytrust.sts.spi.store.fixtures.StsClientStoreTestBase;
19+
import org.eclipse.edc.query.CriterionOperatorRegistryImpl;
1920
import org.junit.jupiter.api.BeforeEach;
2021

2122
public class InMemoryStsClientStoreTest extends StsClientStoreTestBase {
@@ -24,7 +25,7 @@ public class InMemoryStsClientStoreTest extends StsClientStoreTestBase {
2425

2526
@BeforeEach
2627
void setUp() {
27-
store = new InMemoryStsClientStore();
28+
store = new InMemoryStsClientStore(CriterionOperatorRegistryImpl.ofDefaults());
2829
}
2930

3031
@Override
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Apache License, Version 2.0 which is available at
6+
* https://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* SPDX-License-Identifier: Apache-2.0
9+
*
10+
* Contributors:
11+
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
12+
*
13+
*/
14+
15+
plugins {
16+
`java-library`
17+
}
18+
19+
dependencies {
20+
api(project(":spi:common:core-spi"))
21+
api(project(":spi:common:transaction-spi"))
22+
23+
implementation(project(":extensions:common:sql:sql-core"))
24+
implementation(project(":extensions:common:sql:sql-bootstrapper"))
25+
implementation(project(":spi:common:identity-trust-sts-spi"))
26+
implementation(project(":spi:common:transaction-datasource-spi"))
27+
testImplementation(project(":core:common:junit"))
28+
testImplementation(testFixtures(project(":extensions:common:sql:sql-core")))
29+
testImplementation(testFixtures(project(":spi:common:identity-trust-sts-spi")))
30+
31+
}

0 commit comments

Comments
 (0)