From 5dc544ae0522d0e9adfbbeec9b5d7aa8a62ab4a6 Mon Sep 17 00:00:00 2001 From: Tim Smyth Date: Fri, 7 Jun 2024 14:11:38 +0200 Subject: [PATCH 1/2] skip failing dids when building partylist --- .../tir/repository/InMemoryPartiesRepo.java | 210 +++++++++--------- .../repository/InMemoryPartiesRepoTest.java | 64 ++++++ 2 files changed, 172 insertions(+), 102 deletions(-) create mode 100644 src/test/java/org/fiware/iam/tir/repository/InMemoryPartiesRepoTest.java diff --git a/src/main/java/org/fiware/iam/tir/repository/InMemoryPartiesRepo.java b/src/main/java/org/fiware/iam/tir/repository/InMemoryPartiesRepo.java index f16fab1..09c86d2 100644 --- a/src/main/java/org/fiware/iam/tir/repository/InMemoryPartiesRepo.java +++ b/src/main/java/org/fiware/iam/tir/repository/InMemoryPartiesRepo.java @@ -1,10 +1,8 @@ package org.fiware.iam.tir.repository; -import io.micronaut.http.annotation.Part; import io.micronaut.scheduling.annotation.Scheduled; import jakarta.inject.Singleton; import lombok.extern.slf4j.Slf4j; -import org.fiware.iam.did.model.DIDDocumentVO; import org.fiware.iam.satellite.model.TrustedCAVO; import org.fiware.iam.tir.auth.CertificateMapper; import org.fiware.iam.tir.configuration.Party; @@ -21,109 +19,117 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; -import java.util.stream.Stream; @Slf4j @Singleton public class InMemoryPartiesRepo implements PartiesRepo { - private final SatelliteProperties satelliteProperties; - private final IssuersProvider issuersProvider; - private final List parties; - private final DidService didService; - private final CertificateMapper certificateMapper; - - public InMemoryPartiesRepo(SatelliteProperties satelliteProperties, IssuersProvider issuersProvider, DidService didService, CertificateMapper certificateMapper) { - this.parties = new ArrayList<>(satelliteProperties.getParties()); - this.satelliteProperties = satelliteProperties; - this.issuersProvider = issuersProvider; - this.didService = didService; - this.certificateMapper = certificateMapper; - } - - private Optional toTrustedCaVO(X509Certificate caCert) { - - try { - String subject = caCert.getSubjectX500Principal().toString(); - String validity = isValid(caCert); - String fingerprint = certificateMapper.getThumbprint(caCert); - return Optional.of(new TrustedCAVO().status("granted").certificateFingerprint(fingerprint) - .validity(validity).subject(subject)); - } catch (CertificateEncodingException e) { - log.warn("Was not able to get the fingerprint."); - } - return Optional.empty(); - } - - private String isValid(X509Certificate cert) { - try { - cert.checkValidity(); - return "valid"; - } catch (CertificateExpiredException | CertificateNotYetValidException e) { - return "invalid"; - } - } - - @Scheduled(fixedDelay = "15s") - public void updateParties() { - List updatedParties = new ArrayList<>(satelliteProperties.getParties()); - - issuersProvider.getAllTrustedIssuers() - .flatMap(til -> Mono.zip(til.stream().map(this::getPartyForIssuer).toList(), parties -> Arrays.stream(parties).toList())) - .subscribe(partiesList -> { - for (Object partyObject : partiesList) { - if (partyObject instanceof Party party) { - updatedParties.add(party); - } else { - log.warn("Object {} is not a party.", partyObject); - } - } - parties.clear(); - parties.addAll(updatedParties); - }); - } - - - private Mono getPartyForIssuer(TrustedIssuer trustedIssuer) { - return didService.retrieveDidDocument(trustedIssuer.getIssuer()) - .filter(Optional::isPresent) - .map(Optional::get) - .flatMap(didDoc -> didService - .getCertificate(didDoc) - .filter(Optional::isPresent) - .map(Optional::get) - .map(cert -> new Party(didDoc.getId(), didDoc.getId(), didDoc.getId(), "Active", cert, didDoc)) - ); - } - - @Override - public List getParties() { - return parties; - } - - @Override - public List getTrustedCAs() { - List trustedCAVOS = new ArrayList<>(); - - satelliteProperties.getTrustedList().stream() - .forEach(trustedCA -> toTrustedCaVO(certificateMapper.getCertificates(trustedCA.crt()).get(0)).ifPresent( - trustedCAVOS::add)); - - return trustedCAVOS; - } - - @Override - public Optional getPartyById(String id) { - return parties.stream().filter(party -> party.id().equals(id)).findFirst(); - } - - @Override - public Optional getPartyByDID(String did) { - return parties.stream().filter(party -> party.did().equals(did)).findFirst(); - } - - @Override - public void addParty(Party party) { - - } + private final SatelliteProperties satelliteProperties; + private final IssuersProvider issuersProvider; + private final List parties; + private final DidService didService; + private final CertificateMapper certificateMapper; + + public InMemoryPartiesRepo(SatelliteProperties satelliteProperties, IssuersProvider issuersProvider, DidService didService, CertificateMapper certificateMapper) { + this.parties = new ArrayList<>(satelliteProperties.getParties()); + this.satelliteProperties = satelliteProperties; + this.issuersProvider = issuersProvider; + this.didService = didService; + this.certificateMapper = certificateMapper; + } + + private Optional toTrustedCaVO(X509Certificate caCert) { + + try { + String subject = caCert.getSubjectX500Principal().toString(); + String validity = isValid(caCert); + String fingerprint = certificateMapper.getThumbprint(caCert); + return Optional.of(new TrustedCAVO().status("granted").certificateFingerprint(fingerprint) + .validity(validity).subject(subject)); + } catch (CertificateEncodingException e) { + log.warn("Was not able to get the fingerprint."); + } + return Optional.empty(); + } + + private String isValid(X509Certificate cert) { + try { + cert.checkValidity(); + return "valid"; + } catch (CertificateExpiredException | CertificateNotYetValidException e) { + return "invalid"; + } + } + + @Scheduled(fixedDelay = "15s") + public void updateParties() { + try { + List updatedParties = new ArrayList<>(satelliteProperties.getParties()); + issuersProvider.getAllTrustedIssuers() + .flatMap(til -> Mono.zip(til.stream().map(this::getPartyForIssuer).toList(), parties -> Arrays.stream(parties).toList())) + .subscribe(partiesList -> { + for (Object partyObject : partiesList) { + if (partyObject instanceof Optional optional && optional.isPresent() && optional.get() instanceof Party party) { + updatedParties.add(party); + } else { + log.warn("Optional Object {} is not a party or was empty.", partyObject); + } + } + parties.clear(); + parties.addAll(updatedParties); + log.trace("Current parties: {}", updatedParties.stream().map(party -> "%s -> %s".formatted(party.did(), party.crt()))); + }); + } catch (Exception e) { + log.error("Exception occurred while updating parties", e); + throw e; + } + } + + + private Mono> getPartyForIssuer(TrustedIssuer trustedIssuer) { + + return didService.retrieveDidDocument(trustedIssuer.getIssuer()) + .filter(Optional::isPresent) + .map(Optional::get) + .flatMap(didDoc -> didService + .getCertificate(didDoc) + .filter(Optional::isPresent) + .map(Optional::get) + .map(cert -> Optional.of(new Party(didDoc.getId(), didDoc.getId(), didDoc.getId(), "Active", cert, didDoc))) + ).onErrorResume(err -> { + log.error("Failed to retrieve data for issuer {}", trustedIssuer.getIssuer(), err); + return Mono.just(Optional.empty()); + }); + } + + @Override + public List getParties() { + return parties; + } + + @Override + public List getTrustedCAs() { + List trustedCAVOS = new ArrayList<>(); + + satelliteProperties.getTrustedList().stream() + .forEach(trustedCA -> toTrustedCaVO(certificateMapper.getCertificates(trustedCA.crt()).get(0)).ifPresent( + trustedCAVOS::add)); + + return trustedCAVOS; + } + + @Override + public Optional getPartyById(String id) { + return parties.stream().filter(party -> party.id().equals(id)).findFirst(); + } + + @Override + public Optional getPartyByDID(String did) { + return parties.stream().filter(party -> party.did().equals(did)).findFirst(); + } + + @Override + public void addParty(Party party) { + + } } diff --git a/src/test/java/org/fiware/iam/tir/repository/InMemoryPartiesRepoTest.java b/src/test/java/org/fiware/iam/tir/repository/InMemoryPartiesRepoTest.java new file mode 100644 index 0000000..c60b6d7 --- /dev/null +++ b/src/test/java/org/fiware/iam/tir/repository/InMemoryPartiesRepoTest.java @@ -0,0 +1,64 @@ +package org.fiware.iam.tir.repository; + +import io.micronaut.http.client.BlockingHttpClient; +import io.micronaut.http.client.HttpClient; +import org.assertj.core.api.Assertions; +import org.fiware.iam.did.model.DIDDocumentVO; +import org.fiware.iam.tir.auth.CertificateMapper; +import org.fiware.iam.tir.configuration.Party; +import org.fiware.iam.tir.configuration.SatelliteProperties; +import org.fiware.iam.tir.issuers.IssuersProvider; +import org.fiware.iam.tir.issuers.TrustedIssuer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; +import reactor.core.publisher.Mono; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +class InMemoryPartiesRepoTest { + + @Spy + private SatelliteProperties satelliteProperties = spy(new SatelliteProperties().setParties(List.of())); + @Mock + private IssuersProvider issuersProvider; + @Spy + private List parties = spy(new ArrayList<>()); + @Mock + private DidService didService; + @Mock + private CertificateMapper certificateMapper; + + @InjectMocks + private InMemoryPartiesRepo classUnderTest; + + @Test + void updateParties() throws Exception{ + var didDocument = new DIDDocumentVO().id("someId"); + + when(issuersProvider.getAllTrustedIssuers()).thenReturn(Mono.just(List.of(new TrustedIssuer("someId").setIssuer("good"),new TrustedIssuer("someOtherId").setIssuer("failing")))); + when(didService.retrieveDidDocument("good")).thenReturn(Mono.just(Optional.of(didDocument))); + when(didService.retrieveDidDocument("failing")).thenReturn(Mono.error(new IllegalStateException())); + when(didService.getCertificate(any())).thenReturn(Mono.just(Optional.of("cert"))); + classUnderTest.updateParties(); + Assertions.assertThat(classUnderTest.getParties()).hasSize(1); + Assertions.assertThat(classUnderTest.getParties()).element(0).isEqualTo(new Party("someId","someId","someId","Active","cert",didDocument)); + + } +} \ No newline at end of file From ae085dc7314b0240a3d5f58d44baf532b57336b6 Mon Sep 17 00:00:00 2001 From: Tim Smyth Date: Fri, 7 Jun 2024 14:15:46 +0200 Subject: [PATCH 2/2] prev indent --- .../tir/repository/InMemoryPartiesRepo.java | 216 +++++++++--------- 1 file changed, 108 insertions(+), 108 deletions(-) diff --git a/src/main/java/org/fiware/iam/tir/repository/InMemoryPartiesRepo.java b/src/main/java/org/fiware/iam/tir/repository/InMemoryPartiesRepo.java index 09c86d2..ce2fc14 100644 --- a/src/main/java/org/fiware/iam/tir/repository/InMemoryPartiesRepo.java +++ b/src/main/java/org/fiware/iam/tir/repository/InMemoryPartiesRepo.java @@ -24,112 +24,112 @@ @Singleton public class InMemoryPartiesRepo implements PartiesRepo { - private final SatelliteProperties satelliteProperties; - private final IssuersProvider issuersProvider; - private final List parties; - private final DidService didService; - private final CertificateMapper certificateMapper; - - public InMemoryPartiesRepo(SatelliteProperties satelliteProperties, IssuersProvider issuersProvider, DidService didService, CertificateMapper certificateMapper) { - this.parties = new ArrayList<>(satelliteProperties.getParties()); - this.satelliteProperties = satelliteProperties; - this.issuersProvider = issuersProvider; - this.didService = didService; - this.certificateMapper = certificateMapper; - } - - private Optional toTrustedCaVO(X509Certificate caCert) { - - try { - String subject = caCert.getSubjectX500Principal().toString(); - String validity = isValid(caCert); - String fingerprint = certificateMapper.getThumbprint(caCert); - return Optional.of(new TrustedCAVO().status("granted").certificateFingerprint(fingerprint) - .validity(validity).subject(subject)); - } catch (CertificateEncodingException e) { - log.warn("Was not able to get the fingerprint."); - } - return Optional.empty(); - } - - private String isValid(X509Certificate cert) { - try { - cert.checkValidity(); - return "valid"; - } catch (CertificateExpiredException | CertificateNotYetValidException e) { - return "invalid"; - } - } - - @Scheduled(fixedDelay = "15s") - public void updateParties() { - try { - List updatedParties = new ArrayList<>(satelliteProperties.getParties()); - issuersProvider.getAllTrustedIssuers() - .flatMap(til -> Mono.zip(til.stream().map(this::getPartyForIssuer).toList(), parties -> Arrays.stream(parties).toList())) - .subscribe(partiesList -> { - for (Object partyObject : partiesList) { - if (partyObject instanceof Optional optional && optional.isPresent() && optional.get() instanceof Party party) { - updatedParties.add(party); - } else { - log.warn("Optional Object {} is not a party or was empty.", partyObject); - } - } - parties.clear(); - parties.addAll(updatedParties); - log.trace("Current parties: {}", updatedParties.stream().map(party -> "%s -> %s".formatted(party.did(), party.crt()))); - }); - } catch (Exception e) { - log.error("Exception occurred while updating parties", e); - throw e; - } - } - - - private Mono> getPartyForIssuer(TrustedIssuer trustedIssuer) { - - return didService.retrieveDidDocument(trustedIssuer.getIssuer()) - .filter(Optional::isPresent) - .map(Optional::get) - .flatMap(didDoc -> didService - .getCertificate(didDoc) - .filter(Optional::isPresent) - .map(Optional::get) - .map(cert -> Optional.of(new Party(didDoc.getId(), didDoc.getId(), didDoc.getId(), "Active", cert, didDoc))) - ).onErrorResume(err -> { - log.error("Failed to retrieve data for issuer {}", trustedIssuer.getIssuer(), err); - return Mono.just(Optional.empty()); - }); - } - - @Override - public List getParties() { - return parties; - } - - @Override - public List getTrustedCAs() { - List trustedCAVOS = new ArrayList<>(); - - satelliteProperties.getTrustedList().stream() - .forEach(trustedCA -> toTrustedCaVO(certificateMapper.getCertificates(trustedCA.crt()).get(0)).ifPresent( - trustedCAVOS::add)); - - return trustedCAVOS; - } - - @Override - public Optional getPartyById(String id) { - return parties.stream().filter(party -> party.id().equals(id)).findFirst(); - } - - @Override - public Optional getPartyByDID(String did) { - return parties.stream().filter(party -> party.did().equals(did)).findFirst(); - } - - @Override - public void addParty(Party party) { - - } + private final SatelliteProperties satelliteProperties; + private final IssuersProvider issuersProvider; + private final List parties; + private final DidService didService; + private final CertificateMapper certificateMapper; + + public InMemoryPartiesRepo(SatelliteProperties satelliteProperties, IssuersProvider issuersProvider, DidService didService, CertificateMapper certificateMapper) { + this.parties = new ArrayList<>(satelliteProperties.getParties()); + this.satelliteProperties = satelliteProperties; + this.issuersProvider = issuersProvider; + this.didService = didService; + this.certificateMapper = certificateMapper; + } + + private Optional toTrustedCaVO(X509Certificate caCert) { + + try { + String subject = caCert.getSubjectX500Principal().toString(); + String validity = isValid(caCert); + String fingerprint = certificateMapper.getThumbprint(caCert); + return Optional.of(new TrustedCAVO().status("granted").certificateFingerprint(fingerprint) + .validity(validity).subject(subject)); + } catch (CertificateEncodingException e) { + log.warn("Was not able to get the fingerprint."); + } + return Optional.empty(); + } + + private String isValid(X509Certificate cert) { + try { + cert.checkValidity(); + return "valid"; + } catch (CertificateExpiredException | CertificateNotYetValidException e) { + return "invalid"; + } + } + + @Scheduled(fixedDelay = "15s") + public void updateParties() { + try { + List updatedParties = new ArrayList<>(satelliteProperties.getParties()); + issuersProvider.getAllTrustedIssuers() + .flatMap(til -> Mono.zip(til.stream().map(this::getPartyForIssuer).toList(), parties -> Arrays.stream(parties).toList())) + .subscribe(partiesList -> { + for (Object partyObject : partiesList) { + if (partyObject instanceof Optional optional && optional.isPresent() && optional.get() instanceof Party party) { + updatedParties.add(party); + } else { + log.warn("Optional Object {} is not a party or was empty.", partyObject); + } + } + parties.clear(); + parties.addAll(updatedParties); + log.trace("Current parties: {}", updatedParties.stream().map(party -> "%s -> %s".formatted(party.did(), party.crt()))); + }); + } catch (Exception e) { + log.error("Exception occurred while updating parties", e); + throw e; + } + } + + + private Mono> getPartyForIssuer(TrustedIssuer trustedIssuer) { + + return didService.retrieveDidDocument(trustedIssuer.getIssuer()) + .filter(Optional::isPresent) + .map(Optional::get) + .flatMap(didDoc -> didService + .getCertificate(didDoc) + .filter(Optional::isPresent) + .map(Optional::get) + .map(cert -> Optional.of(new Party(didDoc.getId(), didDoc.getId(), didDoc.getId(), "Active", cert, didDoc))) + ).onErrorResume(err -> { + log.error("Failed to retrieve data for issuer {}", trustedIssuer.getIssuer(), err); + return Mono.just(Optional.empty()); + }); + } + + @Override + public List getParties() { + return parties; + } + + @Override + public List getTrustedCAs() { + List trustedCAVOS = new ArrayList<>(); + + satelliteProperties.getTrustedList().stream() + .forEach(trustedCA -> toTrustedCaVO(certificateMapper.getCertificates(trustedCA.crt()).get(0)).ifPresent( + trustedCAVOS::add)); + + return trustedCAVOS; + } + + @Override + public Optional getPartyById(String id) { + return parties.stream().filter(party -> party.id().equals(id)).findFirst(); + } + + @Override + public Optional getPartyByDID(String did) { + return parties.stream().filter(party -> party.did().equals(did)).findFirst(); + } + + @Override + public void addParty(Party party) { + + } }