Skip to content
This repository has been archived by the owner on Sep 15, 2023. It is now read-only.

Commit

Permalink
Merge pull request #12 from admin-ch/develop
Browse files Browse the repository at this point in the history
Release 1.0.0
  • Loading branch information
fabe2913 authored Jun 2, 2021
2 parents c547e63 + de4073e commit 18dee57
Show file tree
Hide file tree
Showing 30 changed files with 309 additions and 157 deletions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2020 Swiss Admin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# CC-API-Gateway-Service
TODO
# CovidCertificate-API-Gateway-Service

The API gateway service provides an API for third party systems.

This project is released by the the Federal Office of Information Technology, Systems and Telecommunication FOITT on behalf of the Federal Office of Public Health FOPH.

## Lombok
Project uses Lombok. Configure your IDE with lombok plugin.

## Local development
TODO
10 changes: 10 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: '3'
services:
db-api-gateway:
image: postgres
ports:
- "3121:5432"
environment:
- POSTGRES_USER=cc-api-gateway
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=cc-api-gateway
16 changes: 15 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>
<groupId>ch.admin.bag.covidcertificate</groupId>
<artifactId>cc-api-gateway-service</artifactId>
<version>0.0.3</version>
<version>1.0.0</version>
<name>cc-api-gateway-service</name>
<description>CC-API-Gateway-Service</description>

Expand All @@ -37,6 +37,10 @@
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
Expand Down Expand Up @@ -133,6 +137,16 @@
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
Expand All @@ -12,9 +11,9 @@ public class Constants {
public static final String KPI_TIMESTAMP_KEY = "ts";
public static final String KPI_TYPE_KEY = "type";
public static final String KPI_CERT_KEY = "cert";
public static final ZoneId SWISS_TIMEZONE = ZoneId.of("Europe/Zurich");
public static final String KPI_CREATE_CERTIFICATE_SYSTEM_KEY = "cc";
public static final String KPI_REVOKE_CERTIFICATE_SYSTEM_KEY = "re";
public static final String KPI_CREATE_CERTIFICATE_TYPE = "cc";
public static final String KPI_REVOKE_CERTIFICATE_TYPE = "re";
public static final String KPI_COMMON_NAME_TYPE = "cn";
public static final String KPI_SYSTEM_API = "api";
public static final DateTimeFormatter LOG_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
public static final String KPI_TYPE_VACCINATION = "v";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ch.admin.bag.covidcertificate.gateway.domain;

import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.UUID;

@Entity
@Getter
@NoArgsConstructor
@Table(name = "kpi")
public class KpiData {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
UUID id;
LocalDateTime timestamp;
String type;
String value;

public KpiData(LocalDateTime timestamp, String type, String value) {
this.timestamp = timestamp;
this.type = type;
this.value = value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ch.admin.bag.covidcertificate.gateway.domain;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.UUID;

public interface KpiDataRepository extends JpaRepository<KpiData, UUID> {
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package ch.admin.bag.covidcertificate.gateway.error;

import ch.admin.bag.covidcertificate.gateway.filters.CustomHttpRequestWrapper;
import org.springframework.http.HttpStatus;

public class ErrorList {
Expand Down Expand Up @@ -71,12 +70,6 @@ private ErrorList() {
public static final String INVALID_BEARER_JSON = ERROR_CODE_KEY + INVALID_BEARER_CODE + ","
+ ERROR_MESSAGE_KEY + INVALID_BEARER_MESSAGE + "}";

private static final int PAYLOAD_TOO_LARGE_CODE = 493;
private static final String PAYLOAD_TOO_LARGE_MESSAGE = "Request payload too large, the maximum payload size is: " + CustomHttpRequestWrapper.MAX_BODY_SIZE + " bytes";
public static final RestError PAYLOAD_TOO_LARGE = new RestError(PAYLOAD_TOO_LARGE_CODE, PAYLOAD_TOO_LARGE_MESSAGE, HttpStatus.PAYLOAD_TOO_LARGE);
public static final String PAYLOAD_TOO_LARGE_JSON = ERROR_CODE_KEY + PAYLOAD_TOO_LARGE_CODE + ","
+ ERROR_MESSAGE_KEY + PAYLOAD_TOO_LARGE_MESSAGE + "}";

// Conflict
public static final String DUPLICATE_UVCI = ERROR_CODE_KEY + 480 + ","
+ ERROR_MESSAGE_KEY + "Duplicate UVCI.}";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package ch.admin.bag.covidcertificate.gateway.error;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.*;
import org.springframework.http.HttpStatus;

import java.io.Serializable;

@AllArgsConstructor
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString
public class RestError implements Serializable {
private int errorCode;
private String errorMessage;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ch.admin.bag.covidcertificate.gateway.filters;

import org.springframework.util.StreamUtils;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;

public class CachedBodyHttpServletRequest extends HttpServletRequestWrapper {

private byte[] cachedBody;

public CachedBodyHttpServletRequest(HttpServletRequest request) throws IOException {
super(request);
InputStream requestInputStream = request.getInputStream();
this.cachedBody = StreamUtils.copyToByteArray(requestInputStream);
}

@Override
public ServletInputStream getInputStream() {
return new CachedBodyServletInputStream(this.cachedBody);
}

@Override
public BufferedReader getReader() {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.cachedBody);
return new BufferedReader(new InputStreamReader(byteArrayInputStream));
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package ch.admin.bag.covidcertificate.gateway.filters;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

@Slf4j
public class CachedBodyServletInputStream extends ServletInputStream {

private final InputStream cachedBodyInputStream;

public CachedBodyServletInputStream(byte[] cachedBody) {
this.cachedBodyInputStream = new ByteArrayInputStream(cachedBody);
}

@Override
public int read() throws IOException {
return cachedBodyInputStream.read();
}

@Override
public boolean isFinished() {
try {
return cachedBodyInputStream.available() == 0;
} catch (IOException e) {
log.error("Exception during reading", e);
throw new IllegalStateException(e);
}
}

@Override
public boolean isReady() {
return true;
}

@Override
public void setReadListener(ReadListener readListener) {
//Method not used
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private static PublicKey getKey(byte[] key) throws KeyException {
}
}

private static boolean checkIntegrity(CustomHttpRequestWrapper request) throws SignatureParseException {
private static boolean checkIntegrity(CachedBodyHttpServletRequest request) throws SignatureParseException {
Base64.Decoder decoder = Base64.getDecoder();
String signaturePublicKey = request.getHeader(HEADER_KEY_NAME);
String signatureHash = request.getHeader(HEADER_HASH_NAME);
Expand All @@ -63,8 +63,6 @@ private static boolean checkIntegrity(CustomHttpRequestWrapper request) throws S
signature.update(body.getBytes());

return signature.verify(decodedHash);
} catch (IOException e) {
log.warn("Unable to read request body", e);
} catch (Exception e) {
log.warn("Error while verifying request integrity", e);
}
Expand All @@ -76,7 +74,7 @@ private static boolean checkIntegrity(CustomHttpRequestWrapper request) throws S

@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
CustomHttpRequestWrapper wrappedRequest = new CustomHttpRequestWrapper(httpServletRequest);
CachedBodyHttpServletRequest wrappedRequest = new CachedBodyHttpServletRequest(httpServletRequest);
RestError restError = null;
try {
if (checkIntegrity(wrappedRequest)) {
Expand Down
Loading

0 comments on commit 18dee57

Please sign in to comment.