diff --git a/src/main/java/ch/admin/bag/covidcode/authcodegeneration/lockdown/LockdownInterceptor.java b/src/main/java/ch/admin/bag/covidcode/authcodegeneration/lockdown/LockdownInterceptor.java index eb5052a..c14908f 100644 --- a/src/main/java/ch/admin/bag/covidcode/authcodegeneration/lockdown/LockdownInterceptor.java +++ b/src/main/java/ch/admin/bag/covidcode/authcodegeneration/lockdown/LockdownInterceptor.java @@ -54,7 +54,8 @@ private boolean isInRange(LocalDateTime now, Endpoint.FromUntil fromUntil) { LocalDateTime from = (fromUntil.getFrom() == null ? LocalDateTime.MIN : fromUntil.getFrom()); LocalDateTime until = (fromUntil.getUntil() == null ? LocalDateTime.MAX : fromUntil.getUntil()); - return Range.between(from, until).contains(now); + boolean isBetween = Range.between(from, until).contains(now); + return isBetween; } private boolean sameUri(String requestUri, Endpoint endpoint) { diff --git a/src/main/java/ch/admin/bag/covidcode/authcodegeneration/lockdown/config/LockdownConfig.java b/src/main/java/ch/admin/bag/covidcode/authcodegeneration/lockdown/config/LockdownConfig.java index 3e3c490..7039fb4 100644 --- a/src/main/java/ch/admin/bag/covidcode/authcodegeneration/lockdown/config/LockdownConfig.java +++ b/src/main/java/ch/admin/bag/covidcode/authcodegeneration/lockdown/config/LockdownConfig.java @@ -10,6 +10,8 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import javax.annotation.PostConstruct; +import javax.naming.ConfigurationException; import java.util.Collections; import java.util.List; @@ -28,4 +30,28 @@ public class LockdownConfig implements WebMvcConfigurer { public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LockdownInterceptor(endpoints)); } + + @PostConstruct + public void validate() throws ConfigurationException { + if (endpoints.isEmpty()) { + log.warn("no active lockdowns - please consider deactivating profile 'lockdown'!"); + } else { + for (Endpoint endpoint : endpoints) { + if (endpoint.getApplicable().isEmpty()) { + log.warn("no active lockdowns for uri '{}' - please consider removing this endpoint!", endpoint.getUri()); + } else { + for (Endpoint.FromUntil fromUntil : endpoint.getApplicable()) { + if (fromUntil.getUntil()==null && fromUntil.getFrom()==null) { + log.warn("endlessly active lockdowns for endpoint '{}' - please consider removing this from/until range!", endpoint.getUri()); + } else if (fromUntil.getUntil()!=null && fromUntil.getFrom()!=null) { + if (!fromUntil.getFrom().isBefore(fromUntil.getUntil())) { + log.error("endpoint '{}': invalid active range from '{}' until '{}'", endpoint.getUri(), fromUntil.getFrom(), fromUntil.getUntil()); + throw new ConfigurationException("Invalid range from="+fromUntil.getFrom()+" until="+fromUntil.getUntil()+" for Endpoint '"+endpoint.getUri()+"'"); + } + } + } + } + } + } + } } diff --git a/src/main/resources/application-lockdown.yml b/src/main/resources/application-lockdown.yml index 45ab22e..c17fb86 100644 --- a/src/main/resources/application-lockdown.yml +++ b/src/main/resources/application-lockdown.yml @@ -5,7 +5,7 @@ lockdown: applicable: - from: 2022-03-22T00:00:00.000Z - until: 2020-03-23T23:59:59.000Z + until: 2022-03-23T23:59:59.000Z - from: 2022-04-01T00:00:00.000Z - @@ -13,7 +13,7 @@ lockdown: applicable: - from: 2022-03-22T00:00:00.000Z - until: 2020-03-23T23:59:59.000Z + until: 2022-03-23T23:59:59.000Z - from: 2022-04-01T00:00:00.000Z - @@ -21,6 +21,6 @@ lockdown: applicable: - from: 2022-03-22T00:00:00.000Z - until: 2020-03-23T23:59:59.000Z + until: 2022-03-23T23:59:59.000Z - from: 2022-04-01T00:00:00.000Z diff --git a/src/test/java/ch/admin/bag/covidcode/authcodegeneration/lockdown/LockdownConfigTest.java b/src/test/java/ch/admin/bag/covidcode/authcodegeneration/lockdown/LockdownConfigTest.java new file mode 100644 index 0000000..422e527 --- /dev/null +++ b/src/test/java/ch/admin/bag/covidcode/authcodegeneration/lockdown/LockdownConfigTest.java @@ -0,0 +1,95 @@ +package ch.admin.bag.covidcode.authcodegeneration.lockdown; + +import ch.admin.bag.covidcode.authcodegeneration.lockdown.config.Endpoint; +import ch.admin.bag.covidcode.authcodegeneration.lockdown.config.LockdownConfig; +import lombok.Builder; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.context.TestPropertySource; + +import javax.naming.ConfigurationException; +import java.time.LocalDateTime; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@ExtendWith(MockitoExtension.class) +public class LockdownConfigTest { + + private LockdownConfig lockdownConfig; + + @BeforeEach + private void init() { + lockdownConfig = new LockdownConfig(); + } + + @Test + public void endpointWithRangeError() { + List endpoints = EndpointBuilder.have() + .endpoint("xyz").fromUntil(LocalDateTime.MAX, LocalDateTime.MIN).build(); + + lockdownConfig.setEndpoints(endpoints); + + assertThrows(ConfigurationException.class, () -> { + lockdownConfig.validate(); + }); + } + + + static class EndpointBuilder { + private Map> endpoints = new TreeMap<>(); + private List fromUntils = new ArrayList<>(); + + + protected static EndpointBuilder have() { + return new EndpointBuilder(); + } + + protected EndpointBuilder fromUntil(LocalDateTime from, LocalDateTime until) { + + Endpoint.FromUntil fromUntil = new Endpoint.FromUntil(); + fromUntil.setFrom(from); + fromUntil.setUntil(until); + fromUntils.add(fromUntil); + + return this; + } + + protected EndpointBuilder endpoint(String uri) { + + List current; + if (endpoints.containsKey(uri)) { + // endpoint followed by ranges + current = endpoints.get(uri); + if (current != fromUntils) { + current.addAll(fromUntils); + } + fromUntils = new ArrayList<>(); + } else { + // ranges followed by endpoint + endpoints.put(uri, fromUntils); + } + + return this; + } + + protected List build() { + List result = new ArrayList<>(); + for (String uri : endpoints.keySet()) { + Endpoint endpoint = new Endpoint(); + endpoint.setUri(uri); + endpoint.setApplicable(endpoints.get(uri)); + result.add(endpoint); + } + + this.endpoints = new TreeMap<>(); + this.fromUntils = new ArrayList<>(); + + return result; + } + } +}