Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions webauthn-server-attestation/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ val integrationTest = task<Test>("integrationTest") {
testClassesDirs = sourceSets["integrationTest"].output.classesDirs
classpath = sourceSets["integrationTest"].runtimeClasspath
shouldRunAfter(tasks.test)
val mdsCacheDir = project.layout.buildDirectory.dir("fido-mds-cache").get().asFile
mdsCacheDir.mkdir()
environment("FIDO_MDS_CACHE_DIR", mdsCacheDir.absolutePath)
}
tasks["check"].dependsOn(integrationTest)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,16 @@ class FidoMetadataDownloaderIntegrationTest
blob shouldBe a[Success[_]]
val trustRootCert =
CertificateParser.parseDer(
TestCaches.getTrustRootCache.get.get.getBytes
TestCaches.trustRootCache.get.getBytes
)

val certChain = TestCaches
.cacheSynchronized(
downloader
.fetchHeaderCertChain(
trustRootCert,
downloader
.parseBlob(TestCaches.getBlobCache.get.get)
.parseBlob(TestCaches.blobCache.get)
.getBlob
.getHeader,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,14 @@ class FidoMetadataServiceIntegrationTest
Try(
FidoMetadataService
.builder()
.useBlob(TestCaches.cacheSynchronized(downloader.loadCachedBlob()))
.useBlob(
TestCaches.cacheSynchronized(
// Since the integration tests cache downloads to file:
// Use refreshBlob() here to always exercise the HTTP part of the downloader,
// and loadCachedBlob() elsewhere to not cause unnecessary server load.
downloader.refreshBlob()
)
)
.build()
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,27 @@ package com.yubico.fido.metadata

import com.yubico.webauthn.data.ByteArray

import java.util.Optional
import java.util.function.Consumer
import java.util.function.Supplier
import scala.jdk.OptionConverters.RichOption
import java.nio.file.Path
import scala.jdk.OptionConverters.RichOptional

object TestCaches {

// Cache downloaded items to avoid unnecessary load on remote servers, and so tests don't have to wait for rate limiting

private var trustRootCache: Option[ByteArray] = None
val getTrustRootCache: Supplier[Optional[ByteArray]] = () =>
trustRootCache.toJava
val setTrustRootCache: Consumer[ByteArray] = trustRoot => {
trustRootCache = Some(trustRoot)
}

private var blobCache: Option[ByteArray] = None
val getBlobCache: Supplier[Optional[ByteArray]] = () => blobCache.toJava
val setBlobCache: Consumer[ByteArray] = blob => { blobCache = Some(blob) }
private val trustRootCacheFile = Path
.of(sys.env.getOrElse("FIDO_MDS_CACHE_DIR", "."), "trust-root-cache.bin")
.toFile
private val blobCacheFile = Path
.of(sys.env.getOrElse("FIDO_MDS_CACHE_DIR", "."), "blob-cache.bin")
.toFile

def trustRootCache: Option[ByteArray] =
cachedDefaultSettingsDownloader
.build()
.readCacheFile(trustRootCacheFile)
.toScala
def blobCache: Option[ByteArray] =
cachedDefaultSettingsDownloader.build().readCacheFile(blobCacheFile).toScala

def cachedDefaultSettingsDownloader
: FidoMetadataDownloader.FidoMetadataDownloaderBuilder =
Expand All @@ -30,9 +32,9 @@ object TestCaches {
"Retrieval and use of this BLOB indicates acceptance of the appropriate agreement located at https://fidoalliance.org/metadata/metadata-legal-terms/"
)
.useDefaultTrustRoot()
.useTrustRootCache(getTrustRootCache, setTrustRootCache)
.useTrustRootCacheFile(trustRootCacheFile)
.useDefaultBlob()
.useBlobCache(getBlobCache, setBlobCache)
.useBlobCacheFile(blobCacheFile)

/** Evaluate <code>expr</code> with an exclusive lock on the test cache. */
def cacheSynchronized[A](expr: => A): A = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,7 @@ private Optional<MetadataBLOB> loadCachedBlobOnly(X509Certificate trustRootCerti
});
}

private Optional<ByteArray> readCacheFile(File cacheFile) throws IOException {
Optional<ByteArray> readCacheFile(File cacheFile) throws IOException {
if (cacheFile.exists() && cacheFile.canRead() && cacheFile.isFile()) {
try (FileInputStream f = new FileInputStream(cacheFile)) {
return Optional.of(readAll(f));
Expand Down
Loading