Skip to content

Commit

Permalink
Merge pull request #7 from eu-digital-green-certificates/feat/refacto…
Browse files Browse the repository at this point in the history
…ring

refactoring validation service endpoint
  • Loading branch information
SchulzeStTSI authored Sep 16, 2021
2 parents 5dad2e1 + cd0563a commit 89678ed
Show file tree
Hide file tree
Showing 20 changed files with 200 additions and 257 deletions.
Binary file modified certs/dev-decorator.jks
Binary file not shown.
Binary file removed certs/dev-test.jks
Binary file not shown.
1 change: 0 additions & 1 deletion docker/CloudFoundry
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ FROM nginx:alpine
COPY --from=build ./app /app
COPY ./nginx/default.conf.template /etc/nginx/conf.d/default.conf
COPY ./entrypoint/entrypoint.sh /entrypoint.sh
COPY ./certs/dev-test.jks /certs/dev-test.jks
COPY ./certs/dev-decorator.jks /certs/dev-decorator.jks
RUN apk --no-cache add openjdk11-jre
EXPOSE 80
Expand Down
1 change: 0 additions & 1 deletion docker/Native
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
FROM adoptopenjdk:11-jre-hotspot
COPY ./target/*.jar /app/app.jar
COPY ./certs/dev-test.jks /app/certs/dev-test.jks
COPY ./certs/dev-decorator.jks /certs/dev-decorator.jks
WORKDIR /app
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar ./app.jar" ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

package eu.europa.ec.dgc.validation.decorator.config;

import io.jsonwebtoken.SignatureAlgorithm;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
Expand All @@ -35,12 +34,6 @@
@ConfigurationProperties("dgc")
public class DgcProperties {

private final GatewayDownload businessRulesDownload = new GatewayDownload();

private final GatewayDownload valueSetsDownload = new GatewayDownload();

private final GatewayDownload countryListDownload = new GatewayDownload();

@DurationUnit(ChronoUnit.SECONDS)
private Duration validationExpire = Duration.ofMinutes(60);

Expand All @@ -54,14 +47,18 @@ public class DgcProperties {

private String activeSignKey;

private List<String> encAliases;
private List<String> encAliases = new ArrayList<>();

private List<String> signAliases;
private List<String> signAliases = new ArrayList<>();

private List<String> keyAliases = new ArrayList<>();

private TokenProperties token;

private List<ServiceProperties> services = new ArrayList<>();

private List<ServiceProperties> endpoints = new ArrayList<>();

@Data
public static final class GatewayDownload {

Expand All @@ -73,33 +70,19 @@ public static final class GatewayDownload {
@Data
public static final class TokenProperties {

public static final String ALGORITHM_ELLIPTIC_CURVE = "ES";

// use "ks" (keyStore) or "config"
private String provider;

private String issuer;

private String type;

private String algorithm;
private TokenInitializeProperties initialize;
}

private int keysize;
@Data
public static final class TokenInitializeProperties {

private int validity;

private String publicKey;

private String privateKey;

private String keyAlgorithm;

public SignatureAlgorithm getSignatureAlgorithm() {
final String name = String.format("%s%d", this.algorithm.toUpperCase(), this.keysize);
return SignatureAlgorithm.forName(name);
}
}

@Data
public static final class ServiceProperties {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ public class IdentityProperties {
private String protocolVersion;

private String serviceIdentityUrl;

private String validationIdentityUrl;


private String consent;

private String servicePovider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
@RequiredArgsConstructor
public class IdentityController {

private static final String PATH_ALL = "/identity";
public static final String PATH_ALL = "/identity";

private static final String PATH_ELEMENT = "/identity/{element}";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public class ValidationStatusController {
@ApiResponse(responseCode = "410", description = "Gone. Subject does not exist anymore"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")
})
@GetMapping(value = PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
@GetMapping(value = PATH, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity reject(@RequestHeader("Authorization") final String token) {
log.debug("Incoming GET request to '{}' with token '{}'", PATH, token);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public static final class PublicKeyJwkIdentityResponse {
private String kid;

private String alg;

private String use;
}

@Data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public static final class PassengerResponse {
private LocalDate birthDate;

private DccStatusResponse dccStatus;

private String serviceIdUsed;
}

@Data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,7 @@ public enum KeyType {

VALIDATION_DECORATOR_ENC_KEY,

VALIDATION_DECORATOR_SIGN_KEY;
VALIDATION_DECORATOR_SIGN_KEY,

VALIDATION_DECORATOR_KEY;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,22 @@

package eu.europa.ec.dgc.validation.decorator.repository;

import eu.europa.ec.dgc.validation.decorator.config.DgcProperties.ServiceProperties;
import eu.europa.ec.dgc.validation.decorator.entity.BookingServiceResultRequest;
import eu.europa.ec.dgc.validation.decorator.entity.BookingServiceTokenContentResponse;
import eu.europa.ec.dgc.validation.decorator.service.AccessTokenService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

@Slf4j
@Service
@RequiredArgsConstructor
public class BookingServiceRepository {
Expand All @@ -55,13 +59,30 @@ public class BookingServiceRepository {
* @return {@link BookingServiceTokenContentResponse}
*/
public BookingServiceTokenContentResponse tokenContent(final String subject) {
final String url = this.tokenContentUrl.replace(PLACEHOLDER_SUBJECT, subject);
return this.tokenContent(subject, null);
}

/**
* Booking service token content endpoint.
*
* @param subject {@link String}
* @param service Used service
* @return {@link BookingServiceTokenContentResponse}
*/
public BookingServiceTokenContentResponse tokenContent(final String subject, final ServiceProperties service) {
final UriComponentsBuilder urlBuilder = UriComponentsBuilder
.fromUriString(this.tokenContentUrl.replace(PLACEHOLDER_SUBJECT, subject));
if (service != null) {
urlBuilder.queryParam("service", service.getId());
}
final String url = urlBuilder.toUriString();

final HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", accessTokenService.buildHeaderToken(subject));

final HttpEntity<String> entity = new HttpEntity<>(headers);

log.debug("REST Call to '{}' starting", url);
final ResponseEntity<BookingServiceTokenContentResponse> response = this.restTpl.exchange(url, HttpMethod.GET,
entity, BookingServiceTokenContentResponse.class);
return response.getBody();
Expand All @@ -81,6 +102,7 @@ public void result(final String subject, final BookingServiceResultRequest body)

final HttpEntity<BookingServiceResultRequest> entity = new HttpEntity<>(body, headers);

log.debug("REST Call to '{}' starting", url);
this.restTpl.exchange(url, HttpMethod.PUT, entity, String.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

import eu.europa.ec.dgc.validation.decorator.config.DgcProperties.ServiceProperties;
import eu.europa.ec.dgc.validation.decorator.dto.DccTokenRequest;
import eu.europa.ec.dgc.validation.decorator.entity.DccValidationRequest;
import eu.europa.ec.dgc.validation.decorator.entity.ValidationServiceIdentityResponse;
import eu.europa.ec.dgc.validation.decorator.entity.ValidationServiceInitializeRequest;
import eu.europa.ec.dgc.validation.decorator.entity.ValidationServiceInitializeResponse;
Expand All @@ -33,27 +32,19 @@
import java.util.Random;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

@Slf4j
@Service
@RequiredArgsConstructor
public class ValidationServiceRepository {

private static final String PLACEHOLDER_SUBJECT = "{subject}";

@Value("${validation.urls.identity}")
private String identityUrl;

@Value("${validation.urls.status}")
private String statusUrl;

private final RestTemplate restTpl;

private final AccessTokenService accessTokenService;
Expand All @@ -64,8 +55,12 @@ public class ValidationServiceRepository {
*
* @return {@link ValidationServiceIdentityResponse}
*/
public ValidationServiceIdentityResponse identity() {
final String url = this.identityUrl;
public ValidationServiceIdentityResponse identity(final ServiceProperties service) {
final String url = UriComponentsBuilder.fromUriString(service.getServiceEndpoint())
.path("identity")
.toUriString();

log.debug("REST Call to '{}' starting", url);
final ResponseEntity<ValidationServiceIdentityResponse> response = restTpl
.getForEntity(url, ValidationServiceIdentityResponse.class);
return response.getBody();
Expand All @@ -81,7 +76,9 @@ public ValidationServiceIdentityResponse identity() {
*/
public ValidationServiceInitializeResponse initialize(
final ServiceProperties service, DccTokenRequest dccToken, String subject) {
final String url = String.format("%s/%s", service.getServiceEndpoint(), subject);
final String url = UriComponentsBuilder.fromUriString(service.getServiceEndpoint())
.pathSegment("initialize", subject)
.toUriString();

final ValidationServiceInitializeRequest body = new ValidationServiceInitializeRequest();
body.setPubKey(dccToken.getPubKey());
Expand All @@ -98,7 +95,6 @@ public ValidationServiceInitializeResponse initialize(
log.debug("REST Call to '{}' starting", url);
final ResponseEntity<ValidationServiceInitializeResponse> response = restTpl
.exchange(url, HttpMethod.PUT, entity, ValidationServiceInitializeResponse.class);
log.debug("REST Call to '{}' done", url);
return response.getBody();
}

Expand All @@ -108,15 +104,18 @@ public ValidationServiceInitializeResponse initialize(
* @param subject {@link String}
* @return {@link ValidationServiceStatusResponse}
*/
public ValidationServiceStatusResponse status(final String subject) {
final String url = this.statusUrl.replace(PLACEHOLDER_SUBJECT, subject);
public ValidationServiceStatusResponse status(final ServiceProperties service, final String subject) {
final String url = UriComponentsBuilder.fromUriString(service.getServiceEndpoint())
.pathSegment("status", subject)
.toUriString();

final HttpHeaders headers = new HttpHeaders();
headers.add("X-Version", "1.0");
headers.add("Authorization", accessTokenService.buildHeaderToken(subject));

final HttpEntity<String> entity = new HttpEntity<>(headers);

log.debug("REST Call to '{}' starting", url);
final ResponseEntity<String> response = restTpl.exchange(url, HttpMethod.GET, entity, String.class);
switch (response.getStatusCode()) {
case OK:
Expand All @@ -128,29 +127,6 @@ public ValidationServiceStatusResponse status(final String subject) {
}
}

/**
* Validation service validate endpoint.
*
* @param service {@link ServiceProperties}
* @param subject {@link String}
* @return {@link String}
*/
public String validate(final ServiceProperties service, final String subject) {
final String url = String.format("%s/%s", service.getServiceEndpoint(), subject);

final HttpHeaders headers = new HttpHeaders();
headers.add("X-Version", "1.0");
headers.add("Authorization", accessTokenService.buildHeaderToken(subject));

final DccValidationRequest body = new DccValidationRequest();
// TODO content source?

final HttpEntity<DccValidationRequest> entity = new HttpEntity<>(body, headers);

final ResponseEntity<String> response = restTpl.exchange(url, HttpMethod.POST, entity, String.class);
return response.getBody();
}

private String buildNonce() {
byte[] randomBytes = new byte[16];
new Random().nextBytes(randomBytes);
Expand Down
Loading

0 comments on commit 89678ed

Please sign in to comment.