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

FIWARE / trusted-issuers-registry / #5

06 Dec 2023 01:52PM UTC coverage: 73.938%. First build
#5

push

web-flow
Merge pull request #18 from FIWARE/react

make it react

34 of 56 new or added lines in 4 files covered. (60.71%)

383 of 518 relevant lines covered (73.94%)

0.74 hits per line

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

86.05
/src/main/java/org/fiware/iam/tir/repository/DidWebService.java
1
package org.fiware.iam.tir.repository;
2

3
import io.micronaut.core.util.StringUtils;
4
import io.micronaut.http.HttpResponse;
5
import io.micronaut.http.HttpStatus;
6
import io.micronaut.http.client.HttpClient;
7
import io.micronaut.http.client.exceptions.HttpClientException;
8
import lombok.RequiredArgsConstructor;
9
import org.fiware.iam.did.model.*;
10
import reactor.core.publisher.Mono;
11

12
import javax.inject.Singleton;
13
import java.net.URLDecoder;
14
import java.nio.charset.StandardCharsets;
15
import java.util.ArrayList;
16
import java.util.Arrays;
17
import java.util.Optional;
18

19
/**
20
 * Handle resolving DID's according to [DID:Web]{https://w3c-ccg.github.io/did-method-web/#create-register}
21
 */
22
@RequiredArgsConstructor
1✔
23
@Singleton
24
public class DidWebService implements DidService {
25

26
    private final HttpClient httpClient;
27

28
    /**
29
     * {@inheritDoc}
30
     */
31
    @Override
32
    public Mono<Optional<DIDDocumentVO>> retrieveDidDocument(String did) {
33
        String documentPath = getDIDDocumentPath(did);
1✔
34
        return Mono.from(httpClient.exchange(documentPath, DIDDocumentVO.class))
1✔
35
                .filter(response -> response.status() == HttpStatus.OK)
1✔
36
                .mapNotNull(HttpResponse::body)
1✔
37
                .map(Optional::ofNullable);
1✔
38
    }
39

40
    /**
41
     * {@inheritDoc}
42
     */
43
    @Override
44
    public Mono<Optional<String>> getCertificate(DIDDocumentVO didDocument) {
45
        if (didDocument.getVerificationMethod() == null) {
1✔
46
            return Mono.just(Optional.empty());
1✔
47
        } else {
48
            return Mono.zip(
1✔
49
                    didDocument.getVerificationMethod()
1✔
50
                            .stream()
1✔
51
                            .map(this::retrieveCertificate)
1✔
52
                            .toList(),
1✔
53
                    oList -> Arrays.stream(oList).map(String.class::cast).findFirst());
1✔
54
        }
55

56
    }
57

58
    private Mono<String> retrieveCertificate(DIDDocumentVerificationMethodInnerVO verificationMethodVO) {
59
        JWKVO publicKeyJwk = getJWK(verificationMethodVO);
1✔
60

61
        //TODO create cert string from other fields (eg n&e)
62
        if (StringUtils.isNotEmpty(publicKeyJwk.getX5u())) {
1✔
63
            return downloadCertificate(publicKeyJwk.getX5u());
1✔
64
        } else if (publicKeyJwk.getX5c() != null && publicKeyJwk.getX5c().size() > 0) {
1✔
NEW
65
            return downloadCertificate(publicKeyJwk.getX5c().get(0));
×
66
        } else {
67
            throw new IllegalArgumentException("Could not retrieve certificate for controller %s and public key JWK %s".formatted(verificationMethodVO.getType(), publicKeyJwk));
1✔
68
        }
69

70
    }
71

72
    private JWKVO getJWK(DIDDocumentVerificationMethodInnerVO verificationMethodVO) {
73
        if (verificationMethodVO instanceof JsonWebKey2020VerificationMethodVO) {
1✔
74
            return ((JsonWebKey2020VerificationMethodVO) verificationMethodVO).getPublicKeyJwk();
1✔
NEW
75
        } else if (verificationMethodVO instanceof RsaVerificationKey2018VerificationMethodVO) {
×
NEW
76
            return ((RsaVerificationKey2018VerificationMethodVO) verificationMethodVO).getPublicKeyJwk();
×
NEW
77
        } else if (verificationMethodVO instanceof Ed25519VerificationKey2019VO) {
×
NEW
78
            return ((Ed25519VerificationKey2019VO) verificationMethodVO).getPublicKeyJwk();
×
79
        } else {
NEW
80
            throw new IllegalArgumentException("Verification method type %s not supported.".formatted(verificationMethodVO.getType()));
×
81
        }
82
    }
83

84
    private Mono<String> downloadCertificate(String certificateAddress) {
85
        try {
86
            return Mono.from(httpClient.retrieve(certificateAddress));
1✔
87
        } catch (HttpClientException e) {
1✔
88
            throw new IllegalArgumentException("Could not retrieve certificate from %s".formatted(certificateAddress), e);
1✔
89
        }
90
    }
91

92
    private String getDIDDocumentPath(String did) {
93
        String[] didParts = did.split(":");
1✔
94
        if (didParts.length < 3) {
1✔
95
            throw new IllegalArgumentException("Did must be at least 3 segments big.");
1✔
96
        }
97
        // Decode optional port usage
98
        didParts[2] = URLDecoder.decode(didParts[2], StandardCharsets.UTF_8);
1✔
99

100
        if (!didParts[1].equals("web")) {
1✔
101
            throw new IllegalArgumentException("Only did web is supported.");
1✔
102
        }
103

104
        if (didParts.length == 3) {
1✔
105
            // standard well-known path
106
            return String.format("https://%s/.well-known/did.json", didParts[2]);
1✔
107
        }
108
        String documentPath = "https://" + didParts[2];
1✔
109

110
        for (int i = 3; i < didParts.length; i++) {
1✔
111
            documentPath += "/" + didParts[i];
1✔
112
        }
113
        documentPath += "/did.json";
1✔
114
        return documentPath;
1✔
115

116
    }
117
}
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