Skip to content

Commit

Permalink
skip failing dids when building partylist
Browse files Browse the repository at this point in the history
  • Loading branch information
pulledtim committed Jun 7, 2024
1 parent c31b50e commit 5dc544a
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 102 deletions.
210 changes: 108 additions & 102 deletions src/main/java/org/fiware/iam/tir/repository/InMemoryPartiesRepo.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<Party> 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<TrustedCAVO> 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<Party> 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<Party> 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<Party> getParties() {
return parties;
}

@Override
public List<TrustedCAVO> getTrustedCAs() {
List<TrustedCAVO> trustedCAVOS = new ArrayList<>();

satelliteProperties.getTrustedList().stream()
.forEach(trustedCA -> toTrustedCaVO(certificateMapper.getCertificates(trustedCA.crt()).get(0)).ifPresent(
trustedCAVOS::add));

return trustedCAVOS;
}

@Override
public Optional<Party> getPartyById(String id) {
return parties.stream().filter(party -> party.id().equals(id)).findFirst();
}

@Override
public Optional<Party> 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<Party> 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<TrustedCAVO> 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<Party> 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<Optional<Party>> 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<Party> getParties() {
return parties;
}

@Override
public List<TrustedCAVO> getTrustedCAs() {
List<TrustedCAVO> trustedCAVOS = new ArrayList<>();

satelliteProperties.getTrustedList().stream()
.forEach(trustedCA -> toTrustedCaVO(certificateMapper.getCertificates(trustedCA.crt()).get(0)).ifPresent(
trustedCAVOS::add));

return trustedCAVOS;
}

@Override
public Optional<Party> getPartyById(String id) {
return parties.stream().filter(party -> party.id().equals(id)).findFirst();
}

@Override
public Optional<Party> getPartyByDID(String did) {
return parties.stream().filter(party -> party.did().equals(did)).findFirst();
}

@Override
public void addParty(Party party) {

}
}
Original file line number Diff line number Diff line change
@@ -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<Party> 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));

}
}

0 comments on commit 5dc544a

Please sign in to comment.