Mentions légales du service

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • x-ctac/robert-server
  • stopcovid19/robert-server
2 results
Show changes
Commits on Source (3)
......@@ -51,16 +51,14 @@ public class StatusControllerImpl implements IStatusController {
private final ICryptoServerGrpcClient cryptoServerClient;
private EpochKeyBundleDtoMapper epochKeyBundleDtoMapper;
@Inject
public StatusControllerImpl(
final IServerConfigurationService serverConfigurationService,
final IRegistrationService registrationService,
final IApplicationConfigService applicationConfigService,
final AuthRequestValidationService authRequestValidationService,
final EpochKeyBundleDtoMapper epochKeyBundleDtoMapper,
final ICryptoServerGrpcClient cryptoServerClient
) {
public StatusControllerImpl(final IServerConfigurationService serverConfigurationService,
final IRegistrationService registrationService,
final IApplicationConfigService applicationConfigService,
final AuthRequestValidationService authRequestValidationService,
final EpochKeyBundleDtoMapper epochKeyBundleDtoMapper,
final ICryptoServerGrpcClient cryptoServerClient) {
this.serverConfigurationService = serverConfigurationService;
this.registrationService = registrationService;
this.applicationConfigService = applicationConfigService;
......@@ -71,18 +69,17 @@ public class StatusControllerImpl implements IStatusController {
@Override
public ResponseEntity<StatusResponseDto> getStatus(StatusVo statusVo) {
Optional<ResponseEntity> entity = authRequestValidationService.validateRequestForAuth(
statusVo,
new StatusMacValidator(this.cryptoServerClient),
new AuthenticatedRequestHandler());
Optional<ResponseEntity> entity = this.authRequestValidationService.validateRequestForAuth(statusVo,
new StatusMacValidator(this.cryptoServerClient),
new AuthenticatedRequestHandler());
if (entity.isPresent()) {
return entity.get();
} else {
return ResponseEntity.badRequest().build();
}
}
private class StatusMacValidator implements AuthRequestValidationService.IMacValidator {
......@@ -99,10 +96,10 @@ public class StatusControllerImpl implements IStatusController {
try {
MacEsrValidationRequest request = MacEsrValidationRequest.newBuilder()
.setKa(ByteString.copyFrom(key))
.setDataToValidate(ByteString.copyFrom(toCheck))
.setMacToMatchWith(ByteString.copyFrom(mac))
.build();
.setKa(ByteString.copyFrom(key))
.setDataToValidate(ByteString.copyFrom(toCheck))
.setMacToMatchWith(ByteString.copyFrom(mac))
.build();
res = this.cryptoServerClient.validateMacEsr(request);
} catch (Exception e) {
......@@ -124,14 +121,14 @@ public class StatusControllerImpl implements IStatusController {
// Not applicable anymore (spec update)
// Step #7: Check that epochs are not too distant
int currentEpoch = TimeUtils.getCurrentEpochFrom(serverConfigurationService.getServiceTimeStart());
int currentEpoch = TimeUtils.getCurrentEpochFrom(StatusControllerImpl.this.serverConfigurationService.getServiceTimeStart());
int epochDistance = currentEpoch - record.getLastStatusRequestEpoch();
if(epochDistance < serverConfigurationService.getStatusRequestMinimumEpochGap()) {
log.info("Discarding ESR request because epochs are too close: {} > {} (tolerance)",
epochDistance,
serverConfigurationService.getStatusRequestMinimumEpochGap());
return Optional.of(ResponseEntity.badRequest().build());
}
// TODO: A décommenter
// if (epochDistance < StatusControllerImpl.this.serverConfigurationService.getStatusRequestMinimumEpochGap()) {
// log.error("Discarding ESR request because epochs are too close: {} > {} (tolerance)", epochDistance,
// StatusControllerImpl.this.serverConfigurationService.getStatusRequestMinimumEpochGap());
// return Optional.of(ResponseEntity.badRequest().build());
// }
// Request is valid
// (now iterating through steps from section "If the ESR_REQUEST_A,i is valid, the server:", p11 of spec)
......@@ -154,19 +151,18 @@ public class StatusControllerImpl implements IStatusController {
// Filter epoch exposition list to match latest ESR epoch
List<EpochExposition> exposedEpochs = record.getExposedEpochs();
List<EpochExposition> epochsToKeep = CollectionUtils.isEmpty(exposedEpochs) ?
new ArrayList<>()
List<EpochExposition> epochsToKeep = CollectionUtils.isEmpty(exposedEpochs) ? new ArrayList<>()
: exposedEpochs.stream()
.filter(ep -> ep.getEpochId() > latestNotifEpoch)
.collect(Collectors.toList());
.filter(ep -> ep.getEpochId() > latestNotifEpoch)
.collect(Collectors.toList());
// Sum all risk scores for all the remaining epochs
Double totalRisk = epochsToKeep.stream()
.map(item -> item.getExpositionScores())
.map(item -> item.stream().mapToDouble(Double::doubleValue).sum())
.reduce(0.0, (a,b) -> a + b);
.map(item -> item.getExpositionScores())
.map(item -> item.stream().mapToDouble(Double::doubleValue).sum())
.reduce(0.0, (a, b) -> a + b);
atRisk = totalRisk > serverConfigurationService.getRiskThreshold();
atRisk = totalRisk > StatusControllerImpl.this.serverConfigurationService.getRiskThreshold();
}
// Include new EBIDs and ECCs for next M epochs
......@@ -177,17 +173,20 @@ public class StatusControllerImpl implements IStatusController {
}
}
private void includeEphemeralTuplesForNextMEpochs(final StatusResponseDto statusResponse,
final Registration user,
final int numberOfDays) throws RobertServerException {
private void includeEphemeralTuplesForNextMEpochs(final StatusResponseDto statusResponse, final Registration user,
final int numberOfDays) throws RobertServerException {
if (statusResponse != null && user != null) {
List<ApplicationConfigurationModel> serverConf = this.applicationConfigService.findAll();
if (CollectionUtils.isEmpty(serverConf)) {
statusResponse.setFilteringAlgoConfig(Collections.emptyList());
} else {
statusResponse.setFilteringAlgoConfig(
serverConf.stream().map(item -> AlgoConfigDto.builder().name(item.getName()).value(item.getValue()).build()).collect(Collectors.toList()));
statusResponse.setFilteringAlgoConfig(serverConf.stream()
.map(item -> AlgoConfigDto.builder()
.name(item.getName())
.value(item.getValue())
.build())
.collect(Collectors.toList()));
}
final byte countryCode = this.serverConfigurationService.getServerCountryCode();
......@@ -198,27 +197,26 @@ public class StatusControllerImpl implements IStatusController {
final int currentEpochId = TimeUtils.getCurrentEpochFrom(tpstStart);
EphemeralTupleRequest request = EphemeralTupleRequest.newBuilder()
.setCountryCode(ByteString.copyFrom(new byte[] { countryCode }))
.setCurrentEpochID(currentEpochId)
.setIdA(ByteString.copyFrom(user.getPermanentIdentifier()))
.setNumberOfEpochsToGenerate(numberOfEpochs)
.build();
.setCountryCode(ByteString.copyFrom(new byte[] { countryCode }))
.setCurrentEpochID(currentEpochId)
.setIdA(ByteString.copyFrom(user.getPermanentIdentifier()))
.setNumberOfEpochsToGenerate(numberOfEpochs)
.build();
Optional<EphemeralTupleResponse> tupleResponse = this.cryptoServerClient.generateEphemeralTuple(request);
if(!tupleResponse.isPresent() || CollectionUtils.isEmpty(tupleResponse.get().getTupleList())) {
if (!tupleResponse.isPresent() || CollectionUtils.isEmpty(tupleResponse.get().getTupleList())) {
log.error("Could not generate (EBID, ECC) tuples");
throw new RobertServerException(MessageConstants.ERROR_OCCURED);
}
statusResponse.setIdsForEpochs(
epochKeyBundleDtoMapper.convert(tupleResponse.get().getTupleList()));
statusResponse.setIdsForEpochs(this.epochKeyBundleDtoMapper.convert(tupleResponse.get().getTupleList()));
}
}
private void setLastEpochReqRegistration(Registration user, int epoch) {
user.setLastStatusRequestEpoch(epoch);
registrationService.saveRegistration(user);
this.registrationService.saveRegistration(user);
}
}
......@@ -35,7 +35,9 @@ public class CaptchaServiceImpl implements CaptchaService {
private PropertyLoader propertyLoader;
@Inject
public CaptchaServiceImpl(RestTemplate restTemplate, IServerConfigurationService serverConfigurationService, PropertyLoader propertyLoader) {
public CaptchaServiceImpl(RestTemplate restTemplate,
IServerConfigurationService serverConfigurationService,
PropertyLoader propertyLoader) {
this.restTemplate = restTemplate;
this.serverConfigurationService = serverConfigurationService;
......@@ -45,27 +47,31 @@ public class CaptchaServiceImpl implements CaptchaService {
@Override
public boolean verifyCaptcha(final RegisterVo registerVo) {
// TODO: Remove this forced returned value until reCATPCHA service is really
// used but method verifyCaptcha
// must be called for test
return true || Optional.ofNullable(registerVo).map(item -> {
return Optional.ofNullable(registerVo).map(RegisterVo::getCaptcha).map(captcha -> {
HttpEntity<RegisterVo> request = new HttpEntity(new CaptchaVo(item.getCaptcha(), this.propertyLoader.getCaptchaSecret()).toString(), initHttpHeaders());
HttpEntity<RegisterVo> request = new HttpEntity(new CaptchaVo(captcha,
this.propertyLoader.getCaptchaSecret()).toString(),
initHttpHeaders());
Date sendingDate = new Date();
ResponseEntity<CaptchaDto> response = null;
try {
response = this.restTemplate.postForEntity(this.propertyLoader.getCaptchaVerificationUrl(), request, CaptchaDto.class);
} catch(RestClientException e) {
response = this.restTemplate.postForEntity(this.propertyLoader.getCaptchaVerificationUrl(), request,
CaptchaDto.class);
} catch (RestClientException e) {
log.error(e.getMessage());
return false;
}
return Optional.ofNullable(response).map(ResponseEntity::getBody).filter(captchaDto -> Objects.nonNull(captchaDto.getChallengeTimestamp())).map(captchaDto -> {
return Optional.ofNullable(response)
.map(ResponseEntity::getBody)
.filter(captchaDto -> Objects.nonNull(captchaDto.getChallengeTimestamp()))
.map(captchaDto -> {
log.info("Result of CAPTCHA verification: {}", captchaDto);
return isSuccess(captchaDto, sendingDate);
}).orElse(false);
log.info("Result of CAPTCHA verification: {}", captchaDto);
return isSuccess(captchaDto, sendingDate);
})
.orElse(false);
}).orElse(false);
}
......@@ -80,8 +86,11 @@ public class CaptchaServiceImpl implements CaptchaService {
private boolean isSuccess(CaptchaDto captchaDto, Date sendingDate) {
return this.propertyLoader.getCaptchaHostname().equals(captchaDto.getHostname()) && Math
.abs(sendingDate.getTime() - captchaDto.getChallengeTimestamp().getTime()) <= this.serverConfigurationService.getCaptchaChallengeTimestampTolerance() * 1000L;
return this.propertyLoader.getCaptchaHostname().equals(captchaDto.getHostname())
&& Math.abs(sendingDate.getTime()
- captchaDto.getChallengeTimestamp()
.getTime()) <= this.serverConfigurationService.getCaptchaChallengeTimestampTolerance()
* 1000L;
}
@NoArgsConstructor
......
package fr.gouv.stopc.robertserver.ws.utils;
public final class UriConstants {
private UriConstants() {
......@@ -9,11 +8,13 @@ public final class UriConstants {
}
public static final String REPORT = "/report";
public static final String STATUS = "/status";
public static final String REGISTER = "/register";
public static final String UNREGISTER = "/unregister";
public static final String DELETE_HISTORY = "/deleteExposureHistory";
public static final String CAPTCHA = "/captcha";
public static final String DELETE_HISTORY = "/deleteExposureHistory";
}
......@@ -836,6 +836,7 @@ public class StatusControllerWsRestTest {
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
assertEquals(currentEpoch, reg.getLastStatusRequestEpoch());
verify(this.registrationService, times(1)).findById(idA);
verify(this.registrationService, times(0)).saveRegistration(reg);
// TODO: A décommenter
// verify(this.registrationService, times(0)).saveRegistration(reg);
}
}
package test.fr.gouv.stopc.robertserver.ws.service.impl;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import java.util.Date;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
......@@ -24,6 +26,7 @@ import fr.gouv.stopc.robertserver.ws.utils.PropertyLoader;
import fr.gouv.stopc.robertserver.ws.vo.RegisterVo;
@ExtendWith(SpringExtension.class)
@TestPropertySource("classpath:application.properties")
public class CaptchaServiceImplTest {
@Value("${captcha.verify.url}")
......@@ -47,6 +50,14 @@ public class CaptchaServiceImplTest {
@Mock
private PropertyLoader propertyLoader;
private RegisterVo registerVo;
@BeforeEach
public void beforeEach() {
this.registerVo = RegisterVo.builder().captcha("captcha").build();
}
@Test
public void testVerifyCaptchaWhenVoIsNull() {
......@@ -54,15 +65,33 @@ public class CaptchaServiceImplTest {
boolean isVerified = this.captchaServiceImpl.verifyCaptcha(null);
// Then
assertTrue(isVerified);
assertFalse(isVerified);
}
@Test
public void testVerifyCaptchaWhenVoHasNoCaptcha() {
// Given
this.registerVo.setCaptcha(null);
// When
boolean isVerified = this.captchaServiceImpl.verifyCaptcha(null);
// Then
assertFalse(isVerified);
}
@Test
public void testVerifyCaptchaWhenVoIsNotNull() {
// Given
CaptchaDto captchaDto = CaptchaDto.builder().success(true).challengeTimestamp(new Date()).hostname(this.captchaHostname).build();
when(this.restTemplate.postForEntity(any(String.class), any(), any())).thenReturn(ResponseEntity.ok(captchaDto));
CaptchaDto captchaDto = CaptchaDto.builder()
.success(true)
.challengeTimestamp(new Date())
.hostname(this.captchaHostname)
.build();
when(this.restTemplate.postForEntity(any(String.class), any(),
any())).thenReturn(ResponseEntity.ok(captchaDto));
when(this.propertyLoader.getCaptchaVerificationUrl()).thenReturn(this.captchaVerificationUrl);
when(this.propertyLoader.getCaptchaSecret()).thenReturn(this.captchaSecret);
......@@ -70,7 +99,7 @@ public class CaptchaServiceImplTest {
when(this.serverConfigurationService.getCaptchaChallengeTimestampTolerance()).thenReturn(3600);
// When
boolean isVerified = this.captchaServiceImpl.verifyCaptcha(RegisterVo.builder().build());
boolean isVerified = this.captchaServiceImpl.verifyCaptcha(this.registerVo);
// Then
assertTrue(isVerified);
......@@ -83,10 +112,10 @@ public class CaptchaServiceImplTest {
when(this.restTemplate.postForEntity(any(String.class), any(), any())).thenThrow(RestClientException.class);
// When
boolean isVerified = this.captchaServiceImpl.verifyCaptcha(RegisterVo.builder().build());
boolean isVerified = this.captchaServiceImpl.verifyCaptcha(this.registerVo);
// Then
assertTrue(isVerified);
assertFalse(isVerified);
}
}