• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FIWARE / contract-management / #95

10 Jun 2026 09:19AM UTC coverage: 1.884% (+0.2%) from 1.724%
#95

push

web-flow
Merge pull request #25 from FIWARE/ticket-44/work

Generate holder did if not provided

53 of 57 new or added lines in 3 files covered. (92.98%)

1 existing line in 1 file now uncovered.

660 of 35030 relevant lines covered (1.88%)

0.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

20.0
/src/main/java/org/fiware/iam/bean/Oid4VpBeanFactory.java
1
package org.fiware.iam.bean;
2

3
import com.fasterxml.jackson.databind.ObjectMapper;
4
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
5
import com.fasterxml.jackson.databind.module.SimpleModule;
6
import com.nimbusds.jose.JWEAlgorithm;
7
import io.github.wistefan.dcql.DCQLEvaluator;
8
import io.github.wistefan.dcql.DcSdJwtCredentialEvaluator;
9
import io.github.wistefan.dcql.JwtCredentialEvaluator;
10
import io.github.wistefan.dcql.VcSdJwtCredentialEvaluator;
11
import io.github.wistefan.dcql.model.CredentialFormat;
12
import io.github.wistefan.dcql.model.TrustedAuthorityType;
13
import io.github.wistefan.oid4vp.HolderSigningService;
14
import io.github.wistefan.oid4vp.OID4VPClient;
15
import io.github.wistefan.oid4vp.SigningService;
16
import io.github.wistefan.oid4vp.client.X509SanDnsClientResolver;
17
import io.github.wistefan.oid4vp.config.HolderConfiguration;
18
import io.github.wistefan.oid4vp.credentials.CredentialsRepository;
19
import io.github.wistefan.oid4vp.credentials.FileSystemCredentialsRepository;
20
import io.github.wistefan.oid4vp.mapping.CredentialFormatDeserializer;
21
import io.github.wistefan.oid4vp.mapping.TrustedAuthorityTypeDeserializer;
22
import io.micronaut.context.annotation.Bean;
23
import io.micronaut.context.annotation.Factory;
24
import io.micronaut.context.annotation.Requires;
25
import jakarta.inject.Singleton;
26

27
import lombok.extern.slf4j.Slf4j;
28
import org.bouncycastle.jce.provider.BouncyCastleProvider;
29
import org.fiware.iam.cert.CertReader;
30
import org.fiware.iam.configuration.Oid4VpConfiguration;
31
import org.fiware.iam.did.DidKeyGenerator;
32

33
import java.net.InetSocketAddress;
34
import java.net.ProxySelector;
35
import java.net.URI;
36
import java.net.http.HttpClient;
37
import java.security.PrivateKey;
38
import java.security.Security;
39
import java.security.cert.TrustAnchor;
40
import java.util.List;
41
import java.util.Set;
42
import java.util.stream.Collectors;
43

44
@Factory
45
@Slf4j
1✔
46
public class Oid4VpBeanFactory {
47

48
    private final CertReader certReader;
49

50
    public Oid4VpBeanFactory(CertReader certReader) {
1✔
51
        this.certReader = certReader;
1✔
52
    }
1✔
53

54
    @Requires(bean = Oid4VpConfiguration.class)
55
    @Singleton
56
    public HttpClient httpClient(Oid4VpConfiguration.ProxyConfig proxyConfig) {
57
        HttpClient.Builder httpClientBuilder = HttpClient.newBuilder();
×
58
        httpClientBuilder.followRedirects(HttpClient.Redirect.NORMAL);
×
59
        if (proxyConfig.useProxy()) {
×
60
            ProxySelector proxySelector = ProxySelector.of(new InetSocketAddress(proxyConfig.proxyHost(), proxyConfig.proxyPort()));
×
61
            httpClientBuilder.proxy(proxySelector);
×
62
        }
63
        return httpClientBuilder.build();
×
64
    }
65

66
    @Requires(bean = Oid4VpConfiguration.class)
67
    @Bean
68
    public CredentialsRepository credentialsRepository(Oid4VpConfiguration oid4VpConfiguration, ObjectMapper objectMapper) {
69
        return new FileSystemCredentialsRepository(oid4VpConfiguration.getCredentialsFolder(), objectMapper);
×
70
    }
71

72
    @Requires(bean = Oid4VpConfiguration.class)
73
    @Bean
74
    public OID4VPClient oid4VPClient(HttpClient httpClient, ObjectMapper objectMapper, Oid4VpConfiguration oid4VpConfiguration, CredentialsRepository credentialsRepository) {
75
        Security.addProvider(new BouncyCastleProvider());
×
76

77
        ObjectMapper authObjectMapper = objectMapper.copy();
×
78
        authObjectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
×
79
        SimpleModule deserializerModule = new SimpleModule();
×
80
        deserializerModule.addDeserializer(CredentialFormat.class, new CredentialFormatDeserializer());
×
81
        deserializerModule.addDeserializer(TrustedAuthorityType.class, new TrustedAuthorityTypeDeserializer());
×
82
        authObjectMapper.registerModule(deserializerModule);
×
83

84
        PrivateKey privateKey = certReader.loadPrivateKey(oid4VpConfiguration.getHolder().keyPath());
×
NEW
85
        URI holderId = resolveHolderId(oid4VpConfiguration.getHolder(), privateKey);
×
86
        HolderConfiguration holderConfiguration = new HolderConfiguration(
×
87
                holderId,
NEW
88
                holderId.toString(),
×
UNCOV
89
                JWEAlgorithm.parse(oid4VpConfiguration.getHolder().signatureAlgorithm()),
×
90
                privateKey);
91
        SigningService signingService = new HolderSigningService(holderConfiguration, objectMapper);
×
92

93
        Set<TrustAnchor> trustAnchors = oid4VpConfiguration.getTrustAnchors()
×
94
                .stream()
×
95
                .map(certReader::loadCertificates)
×
96
                .flatMap(List::stream)
×
97
                .map(c -> new TrustAnchor(c, null))
×
98
                .collect(Collectors.toSet());
×
99

100

101
        if (trustAnchors.isEmpty()) {
×
102
            try {
103
                log.info("No trust anchors provided, loading system trust anchors");
×
104
                trustAnchors = X509SanDnsClientResolver.getTrustAnchors();
×
105
            } catch (Exception e) {
×
106
                throw new RuntimeException("Failed to load system trust anchors and no additional trust anchors provided.", e);
×
107
            }
×
108
        }
109

110
        X509SanDnsClientResolver clientResolver = new X509SanDnsClientResolver(trustAnchors, oid4VpConfiguration.isEnableRevocation());
×
111

112
        DCQLEvaluator dcqlEvaluator = new DCQLEvaluator(List.of(
×
113
                new JwtCredentialEvaluator(),
114
                new DcSdJwtCredentialEvaluator(),
115
                new VcSdJwtCredentialEvaluator()));
116

117
        return new OID4VPClient(
×
118
                httpClient,
119
                holderConfiguration,
120
                authObjectMapper,
121
                List.of(clientResolver),
×
122
                dcqlEvaluator,
123
                credentialsRepository,
124
                signingService);
125
    }
126

127
    /**
128
     * Resolves the holder ID URI. If the holder configuration provides an explicit
129
     * {@code holderId}, it is returned as-is. Otherwise, a {@code did:key} URI is
130
     * automatically generated from the holder's private key using {@link DidKeyGenerator}.
131
     *
132
     * <p>Package-private for unit testing in {@code Oid4VpBeanFactoryTest}.</p>
133
     *
134
     * @param holder     the holder configuration record
135
     * @param privateKey the holder's private key used for did:key generation when holderId is null
136
     * @return the resolved holder ID URI
137
     */
138
    URI resolveHolderId(Oid4VpConfiguration.Holder holder, PrivateKey privateKey) {
139
        if (holder.holderId() != null) {
1✔
140
            return holder.holderId();
1✔
141
        }
142
        URI generatedDidKey = DidKeyGenerator.generateDidKey(privateKey);
1✔
143
        log.info("No holderId configured, generated did:key from holder public key: {}", generatedDidKey);
1✔
144
        return generatedDidKey;
1✔
145
    }
146
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc