Skip to content

Commit

Permalink
Make non-repudiation PostgreSQL back-end certificate adding idempotent (
Browse files Browse the repository at this point in the history
#9024)

Closes #9021

changelog_begin
changelog_end
  • Loading branch information
stefanobaghino-da committed Mar 4, 2021
1 parent eaf7fb6 commit d347934
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class PostgresqlCertificateRepository(transactor: Transactor[IO])(implicit
getCertificate(fingerprint).query[X509Certificate].option.transact(transactor).unsafeRunSync()

private def putKey(fingerprint: FingerprintBytes, certificate: X509Certificate): Fragment =
fr"insert into" ++ table ++ fr"""(fingerprint, certificate) values ($fingerprint, $certificate)"""
fr"insert into" ++ table ++ fr"""(fingerprint, certificate) values ($fingerprint, $certificate) on conflict do nothing"""

override def put(certificate: X509Certificate): FingerprintBytes = {
val fingerprint = FingerprintBytes.compute(certificate)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ final class TablesSpec
}
}

it should "guarantee that adding a certificate is idempotent" in {
initializeDatabase(postgresDatabase.url, maxPoolSize = 10).use { db =>
val (_, expectedCertificate) = generateKeyAndCertificate()
val fingerprint1 = db.certificates.put(expectedCertificate)
val fingerprint2 = db.certificates.put(expectedCertificate)
fingerprint1 shouldEqual fingerprint2
val certificate = db.certificates.get(fingerprint1)
certificate.value.getEncoded shouldEqual expectedCertificate.getEncoded
}
}

it should "correctly read and write signed payloads" in {
initializeDatabase(postgresDatabase.url, maxPoolSize = 10).use { db =>
val (privateKey, expectedCertificate) = generateKeyAndCertificate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ import com.codahale.metrics.Timer
object CertificateRepository {

trait Read {

def get(fingerprint: FingerprintBytes): Option[X509Certificate]

}

trait Write {

/** Must guarantee idempotence. */
def put(certificate: X509Certificate): FingerprintBytes

}

final class Timed(timer: Timer, delegate: Read) extends Read {
Expand Down

0 comments on commit d347934

Please sign in to comment.