This repository has been archived by the owner on May 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add db_encryption * Add db_encryption * Add db_encryption * Add db_encryption * Add unittest for db_encryption * - QuickTestArchive Feature started: - controller added - Entity added - Repository added - Service added - bugfix: - removed some utests (annotation missing now, utests broken by ???) - state: application context destroyed by fetching branch - not runnable version now * Reformate Code * - fix: uri wrong - removed extends entity - change blob to clob - revert delete utests - state: runnig version now * - removed tests without assert * - pdf upload check content type added - pdf encryption added - seperated archive entity to own chnage id in liquibase changelog * - current version * Add statistictable * Add statisticstable * - change statistics id to long - add findByPocAndDate to statistics repo - rollback scope for transaction in archive optimized - finished statistics functions * - security options enabled * - log outputs added - log outputs optimized - refactoring utests - utests added * - Fix statistics endpoint - Fix update testresult endpoint - reformat archivetable * - Insert Test for Utilities - Fix Utilities * Added birthday column to QuickTest * - refactoring move create archive to testResult - birthday fixed - pdf creator built in - state: proving * - Change KeycloakRealm to load by Request * - Change KeycloakRealm to load by Request * - Fix getPdf * - Fix KeycloakDeploymentBuilder => default if no auth * - change pdf endpoint - change statistics repository * - Fix check if hashedGuid exist in archive * Added endpoint for querying archive, moved testBrand to testResult endpoint * - hashedGuid added to response (GUI needs for request pdf) * - Fix pdf-generation * - debug lines removed * Fixed testResult endpoint Co-authored-by: Matthias Baude <[email protected]> Co-authored-by: Eduard Gerling <[email protected]>
- Loading branch information
1 parent
cd0798f
commit d53bab7
Showing
38 changed files
with
1,503 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
src/main/java/app/coronawarn/quicktest/config/QuicktestKeycloakSpringBootConfigResolver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package app.coronawarn.quicktest.config; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
import java.util.Base64; | ||
import lombok.SneakyThrows; | ||
import org.keycloak.adapters.KeycloakDeployment; | ||
import org.keycloak.adapters.KeycloakDeploymentBuilder; | ||
import org.keycloak.adapters.spi.HttpFacade; | ||
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; | ||
import org.keycloak.adapters.springboot.KeycloakSpringBootProperties; | ||
import org.keycloak.representations.adapters.config.AdapterConfig; | ||
import org.springframework.boot.configurationprocessor.json.JSONObject; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Configuration | ||
public class QuicktestKeycloakSpringBootConfigResolver extends KeycloakSpringBootConfigResolver { | ||
private final AdapterConfig adapterConfig; | ||
|
||
public QuicktestKeycloakSpringBootConfigResolver(KeycloakSpringBootProperties properties) { | ||
this.adapterConfig = properties; | ||
} | ||
|
||
@SneakyThrows | ||
@Override | ||
public KeycloakDeployment resolve(HttpFacade.Request request) { | ||
AdapterConfig tenantConfig = this.adapterConfig; | ||
JSONObject jwtBodyAsJson = null; | ||
String realm = null; | ||
if ( | ||
request.getHeader("Authorization") != null | ||
&& request.getHeader("Authorization").split("Bearer ").length > 1 | ||
&& request.getHeader("Authorization").split("Bearer ")[1].split("\\.").length > 1 | ||
) { | ||
//Remove Bearer and split in three parts => take the second with the body information | ||
String jwtBody = request.getHeader("Authorization").split("Bearer ")[1].split("\\.")[1]; | ||
//Decode and convert in Json | ||
jwtBodyAsJson = new JSONObject(new String(Base64.getDecoder().decode(jwtBody), | ||
StandardCharsets.UTF_8)); | ||
} | ||
if ( | ||
jwtBodyAsJson != null | ||
&& jwtBodyAsJson.get("iss") != null | ||
&& jwtBodyAsJson.get("iss").toString().split("/").length > 0) { | ||
//get issuerUri from body and split url by / | ||
String[] issuerUriElements = jwtBodyAsJson.get("iss").toString().split("/"); | ||
//get last element from issuerUriElements => realm name | ||
realm = issuerUriElements[issuerUriElements.length - 1]; | ||
} | ||
if (realm != null) { | ||
tenantConfig.setRealm(realm); | ||
} | ||
return KeycloakDeploymentBuilder.build(tenantConfig); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
136 changes: 136 additions & 0 deletions
136
src/main/java/app/coronawarn/quicktest/controller/QuickTestArchiveController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/*- | ||
* ---license-start | ||
* Corona-Warn-App / cwa-quick-test-backend | ||
* --- | ||
* Copyright (C) 2021 T-Systems International GmbH and all other contributors | ||
* --- | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* ---license-end | ||
*/ | ||
|
||
package app.coronawarn.quicktest.controller; | ||
|
||
import static app.coronawarn.quicktest.config.SecurityConfig.ROLE_LAB; | ||
|
||
import app.coronawarn.quicktest.domain.QuickTestArchive; | ||
import app.coronawarn.quicktest.model.QuickTestArchiveListResponse; | ||
import app.coronawarn.quicktest.model.QuickTestArchiveResponse; | ||
import app.coronawarn.quicktest.service.QuickTestArchiveService; | ||
import app.coronawarn.quicktest.service.QuickTestServiceException; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
import javax.validation.constraints.Max; | ||
import javax.validation.constraints.Min; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.modelmapper.ModelMapper; | ||
import org.modelmapper.TypeToken; | ||
import org.springframework.format.annotation.DateTimeFormat; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.access.annotation.Secured; | ||
import org.springframework.validation.annotation.Validated; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestMethod; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@Slf4j | ||
@RestController | ||
@RequestMapping(value = "/api/quicktestarchive") | ||
@RequiredArgsConstructor | ||
@Validated | ||
public class QuickTestArchiveController { | ||
|
||
private final QuickTestArchiveService quickTestArchiveService; | ||
private final ModelMapper modelMapper; | ||
|
||
/** | ||
* Endpoint for receiving pdf. | ||
* | ||
* @param hashedGuid containing the full hashed guid. | ||
* @return PDF | ||
*/ | ||
@Operation( | ||
summary = "Response quicktest as PDF", | ||
description = "PDF stored in DB will be responsed for download if found." | ||
) | ||
@ApiResponses(value = { | ||
@ApiResponse(responseCode = "200", description = "PDF found"), | ||
@ApiResponse(responseCode = "404", description = "Quicktest not found"), | ||
@ApiResponse(responseCode = "500", description = "Inserting failed because of internal error.")}) | ||
@RequestMapping(path = "/{hashedGuid}/pdf", method = RequestMethod.GET, produces = MediaType.APPLICATION_PDF_VALUE) | ||
@Secured(ROLE_LAB) | ||
public ResponseEntity<byte[]> createQuickTestArchive( | ||
@PathVariable String hashedGuid) { | ||
try { | ||
return ResponseEntity.ok() | ||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" | ||
+ "Schnelltest_" + hashedGuid + "\"") | ||
.body(quickTestArchiveService.getPdf(hashedGuid)); | ||
} catch (QuickTestServiceException e) { | ||
if (e.getReason() == QuickTestServiceException.Reason.NOT_FOUND) { | ||
return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); | ||
} else { | ||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); | ||
} | ||
} catch (Exception e) { | ||
log.error("Couldn't prepare stored pdf for download. Message: {}", e.getMessage()); | ||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); | ||
} | ||
} | ||
|
||
/** | ||
* Endpoint for getting quicktests in archive table by query parameters. | ||
* | ||
* @return QuickTestArchiveListResponse with all found archives | ||
*/ | ||
@Operation( | ||
summary = "Find quicktests in archive", | ||
description = "Returns all found quicktests in archive for search parameters" | ||
) | ||
@ApiResponses(value = { | ||
@ApiResponse(responseCode = "200", description = "Successful"), | ||
@ApiResponse(responseCode = "500", description = "Query failed because of an internal server error") | ||
}) | ||
@GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE) | ||
@Secured(ROLE_LAB) | ||
public ResponseEntity<QuickTestArchiveListResponse> findArchivesByTestResultAndUpdatedAtBetween( | ||
@RequestParam @Min(5) @Max(8) Short testResult, | ||
@RequestParam("dateFrom") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime localDateFrom, | ||
@RequestParam("dateTo") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime localDateTo) { | ||
try { | ||
List<QuickTestArchive> archives = quickTestArchiveService.findByTestResultAndUpdatedAtBetween( | ||
testResult, localDateFrom, localDateTo); | ||
TypeToken<List<QuickTestArchiveResponse>> typeToken = new TypeToken<List<QuickTestArchiveResponse>>() { | ||
}; | ||
List<QuickTestArchiveResponse> quickTestArchiveResponses = modelMapper.map( | ||
archives, | ||
typeToken.getType() | ||
); | ||
QuickTestArchiveListResponse response = new QuickTestArchiveListResponse(); | ||
response.setQuickTestArchives(quickTestArchiveResponses); | ||
return ResponseEntity.ok(response); | ||
} catch (Exception e) { | ||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
src/main/java/app/coronawarn/quicktest/controller/QuickTestStatisticsController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/*- | ||
* ---license-start | ||
* Corona-Warn-App / cwa-quick-test-backend | ||
* --- | ||
* Copyright (C) 2021 T-Systems International GmbH and all other contributors | ||
* --- | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* ---license-end | ||
*/ | ||
|
||
package app.coronawarn.quicktest.controller; | ||
|
||
import static app.coronawarn.quicktest.config.SecurityConfig.ROLE_COUNTER; | ||
|
||
import app.coronawarn.quicktest.model.QuickTestStatisticsResponse; | ||
import app.coronawarn.quicktest.service.QuickTestServiceException; | ||
import app.coronawarn.quicktest.service.QuickTestStatisticsService; | ||
import app.coronawarn.quicktest.utils.Utilities; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.modelmapper.ModelMapper; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.access.annotation.Secured; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@Slf4j | ||
@RestController | ||
@RequestMapping(value = "/api/quickteststatistics") | ||
@RequiredArgsConstructor | ||
public class QuickTestStatisticsController { | ||
|
||
private final QuickTestStatisticsService quickTestStatisticsService; | ||
|
||
private final ModelMapper modelMapper; | ||
|
||
private final Utilities utilities; | ||
|
||
|
||
//TODO check role | ||
/** | ||
* Endpoint for get statistic for QuickTest. | ||
* | ||
* @return QuickTestStatisticsResponse with total and positive count | ||
*/ | ||
@Operation( | ||
summary = "Get quicktest statistics", | ||
description = "Returns the statistics for total and positive counts for today" | ||
) | ||
@ApiResponses(value = { | ||
@ApiResponse(responseCode = "200", description = "Get statistic data"), | ||
@ApiResponse(responseCode = "500", description = "Inserting failed because of internal error.")}) | ||
@GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE) | ||
@Secured(ROLE_COUNTER) | ||
public ResponseEntity<QuickTestStatisticsResponse> getQuicktestStatistics() { | ||
try { | ||
QuickTestStatisticsResponse quickTestStatisticsResponse = modelMapper.map( | ||
quickTestStatisticsService.getStatistics(utilities.getIdsFromToken()), | ||
QuickTestStatisticsResponse.class); | ||
|
||
return ResponseEntity.ok(quickTestStatisticsResponse); | ||
} catch (QuickTestServiceException e) { | ||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); | ||
} | ||
|
||
} | ||
|
||
} |
32 changes: 32 additions & 0 deletions
32
src/main/java/app/coronawarn/quicktest/dbencryption/DbEncryptionByteArrayConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package app.coronawarn.quicktest.dbencryption; | ||
|
||
import java.security.InvalidAlgorithmParameterException; | ||
import java.security.InvalidKeyException; | ||
import javax.crypto.BadPaddingException; | ||
import javax.crypto.IllegalBlockSizeException; | ||
import javax.persistence.AttributeConverter; | ||
import javax.persistence.PersistenceException; | ||
|
||
public class DbEncryptionByteArrayConverter implements AttributeConverter<byte[], String> { | ||
|
||
@Override | ||
public String convertToDatabaseColumn(byte[] s) { | ||
try { | ||
return DbEncryptionService.getInstance().encryptByteArray(s); | ||
} catch (InvalidAlgorithmParameterException | InvalidKeyException | ||
| BadPaddingException | IllegalBlockSizeException e) { | ||
throw new PersistenceException(e); | ||
} | ||
} | ||
|
||
@Override | ||
public byte[] convertToEntityAttribute(String s) { | ||
try { | ||
return DbEncryptionService.getInstance().decryptByteArray(s); | ||
} catch (InvalidAlgorithmParameterException | InvalidKeyException | ||
| BadPaddingException | IllegalBlockSizeException e) { | ||
throw new PersistenceException(e); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.