Skip to content

Commit

Permalink
Merge pull request #263 from DP-3T/feature/use-key-tag-naming
Browse files Browse the repository at this point in the history
Use key tag naming
  • Loading branch information
martinalig committed Oct 13, 2020
2 parents e9337ca + 042095c commit 0f0c6fa
Showing 1 changed file with 22 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,10 @@
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
* This is a new controller to simplify the sending and receiving of keys. It will be used by the
* new SwissCovid client and allows for ENV2 usage.
*/
/** This is a new controller to simplify the sending and receiving of keys using ENv1.5/ENv2. */
@Controller
@RequestMapping("/v2/gaen")
@Documentation(
description =
"The GAEN V2 endpoint for the mobile clients supporting international key sharing")
@Documentation(description = "The GAEN V2 endpoint for the mobile clients supporting ENv1.5/ENv2")
public class GaenV2Controller {

private static final Logger logger = LoggerFactory.getLogger(GaenV2Controller.class);
Expand All @@ -72,6 +67,8 @@ public class GaenV2Controller {
private final Duration exposedListCacheControl;
private final Duration retentionPeriod;

private static final String HEADER_X_KEY_BUNDLE_TAG = "x-key-bundle-tag";

public GaenV2Controller(
InsertManager insertManager,
ValidateRequest validateRequest,
Expand Down Expand Up @@ -120,9 +117,9 @@ public GaenV2Controller(
@RequestHeader(value = "User-Agent")
@Documentation(
description =
"App Identifier (PackageName/BundleIdentifier) + App-Version + OS (Android/iOS)"
+ " + OS-Version",
example = "ch.ubique.android.starsdk;1.0;iOS;13.3")
"App Identifier (PackageName/BundleIdentifier) + App-Version +"
+ " OS (Android/iOS) + OS-Version",
example = "ch.ubique.android.dp3t;1.0;iOS;13.3")
String userAgent,
@AuthenticationPrincipal
@Documentation(description = "JWT token that can be verified by the backend server")
Expand Down Expand Up @@ -152,49 +149,50 @@ public GaenV2Controller(
// GET for Key Download
@GetMapping(value = "/exposed")
@Documentation(
description =
"Requests the exposed keys published _since_ originating from list of _country_",
description = "Requests keys published _after_ lastKeyBundleTag.",
responses = {
"200 => zipped export.bin and export.sig of all keys in that interval",
"404 => Invalid _since_ (too far in the past/future, not at bucket" + " boundaries)"
"404 => Invalid _lastKeyBundleTag_"
})
public @ResponseBody ResponseEntity<byte[]> getExposedKeys(
@Documentation(
description =
"Timestamp to retrieve exposed keys since, in milliseconds since Unix epoch"
+ " (1970-01-01). It must indicate the beginning of a bucket. Optional, if"
+ " no since set, all keys for the retention period are returned",
"Only retrieve keys published after the specified key-bundle"
+ " tag. Optional, if no tag set, all keys for the"
+ " retention period are returned",
example = "1593043200000")
@RequestParam(required = false)
Long since)
Long lastKeyBundleTag)
throws BadBatchReleaseTimeException, InvalidKeyException, SignatureException,
NoSuchAlgorithmException, IOException {
var now = UTCInstant.now();

if (since == null) {
// if no since given, go back to the start of the retention period and select next bucket.
since = now.minus(retentionPeriod).roundToNextBucket(releaseBucketDuration).getTimestamp();
if (lastKeyBundleTag == null) {
// if no lastKeyBundleTag given, go back to the start of the retention period and
// select next bucket.
lastKeyBundleTag =
now.minus(retentionPeriod).roundToNextBucket(releaseBucketDuration).getTimestamp();
}
var keysSince = UTCInstant.ofEpochMillis(since);
var keysSince = UTCInstant.ofEpochMillis(lastKeyBundleTag);

if (!validationUtils.isValidBatchReleaseTime(keysSince, now)) {
return ResponseEntity.notFound().build();
}
UTCInstant publishedUntil = now.roundToBucketStart(releaseBucketDuration);
UTCInstant keyBundleTag = now.roundToBucketStart(releaseBucketDuration);

List<GaenKey> exposedKeys = dataService.getSortedExposedSince(keysSince, now);

if (exposedKeys.isEmpty()) {
return ResponseEntity.noContent()
.cacheControl(CacheControl.maxAge(exposedListCacheControl))
.header("X-PUBLISHED-UNTIL", Long.toString(publishedUntil.getTimestamp()))
.header(HEADER_X_KEY_BUNDLE_TAG, Long.toString(keyBundleTag.getTimestamp()))
.build();
}
ProtoSignatureWrapper payload = gaenSigner.getPayloadV2(exposedKeys);

return ResponseEntity.ok()
.cacheControl(CacheControl.maxAge(exposedListCacheControl))
.header("X-PUBLISHED-UNTIL", Long.toString(publishedUntil.getTimestamp()))
.header(HEADER_X_KEY_BUNDLE_TAG, Long.toString(keyBundleTag.getTimestamp()))
.body(payload.getZip());
}

Expand Down

0 comments on commit 0f0c6fa

Please sign in to comment.