From f159d1c6708dcc51146bd214523e0c6e03416ae0 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone <exarkun@twistedmatrix.com> Date: Wed, 1 Apr 2020 08:49:45 -0400 Subject: [PATCH] Don't allow unblinded tokens for unknown vouchers --- src/_zkapauthorizer/model.py | 2 + src/_zkapauthorizer/tests/test_model.py | 54 +++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/_zkapauthorizer/model.py b/src/_zkapauthorizer/model.py index 530fb88..6a9b29c 100644 --- a/src/_zkapauthorizer/model.py +++ b/src/_zkapauthorizer/model.py @@ -350,6 +350,8 @@ class VoucherStore(object): voucher, ), ) + if cursor.rowcount == 0: + raise ValueError("Cannot insert tokens for unknown voucher; add voucher first") cursor.executemany( """ INSERT INTO [unblinded-tokens] VALUES (?) diff --git a/src/_zkapauthorizer/tests/test_model.py b/src/_zkapauthorizer/tests/test_model.py index e4052d2..c4885ed 100644 --- a/src/_zkapauthorizer/tests/test_model.py +++ b/src/_zkapauthorizer/tests/test_model.py @@ -328,6 +328,29 @@ class VoucherTests(TestCase): ) +def paired_tokens(data): + """ + Draw two lists of the same length, one of random tokens and one of + unblinded tokens. + + :rtype: ([RandomTokens], [UnblindedTokens]) + """ + num_tokens = data.draw(integers(min_value=1, max_value=1000)) + r = data.draw(lists( + random_tokens(), + min_size=num_tokens, + max_size=num_tokens, + unique=True, + )) + u = data.draw(lists( + unblinded_tokens(), + min_size=num_tokens, + max_size=num_tokens, + unique=True, + )) + return r, u + + class UnblindedTokenStoreTests(TestCase): """ Tests for ``UnblindedToken``-related functionality of ``VoucherStore``. @@ -339,14 +362,37 @@ class UnblindedTokenStoreTests(TestCase): dummy_ristretto_keys(), lists(unblinded_tokens(), unique=True), ) - def test_unblinded_tokens_round_trip(self, get_config, now, voucher_value, public_key, tokens): + def test_unblinded_tokens_without_voucher(self, get_config, now, voucher_value, public_key, unblinded_tokens): + """ + Unblinded tokens for a voucher which has not been added to the store cannot be inserted. + """ + store = self.useFixture(TemporaryVoucherStore(get_config, lambda: now)).store + try: + result = store.insert_unblinded_tokens_for_voucher(voucher_value, public_key, unblinded_tokens) + except ValueError: + pass + except Exception as e: + self.fail("insert_unblinded_tokens_for_voucher raised the wrong exception: {}".format(e)) + else: + self.fail("insert_unblinded_tokens_for_voucher didn't raise, returned: {}".format(result)) + + @given( + tahoe_configs(), + datetimes(), + vouchers(), + dummy_ristretto_keys(), + data(), + ) + def test_unblinded_tokens_round_trip(self, get_config, now, voucher_value, public_key, data): """ Unblinded tokens that are added to the store can later be retrieved. """ + random_tokens, unblinded_tokens = paired_tokens(data) store = self.useFixture(TemporaryVoucherStore(get_config, lambda: now)).store - store.insert_unblinded_tokens_for_voucher(voucher_value, public_key, tokens) - retrieved_tokens = store.extract_unblinded_tokens(len(tokens)) - self.expectThat(tokens, AfterPreprocessing(sorted, Equals(retrieved_tokens))) + store.add(voucher_value, lambda: random_tokens) + store.insert_unblinded_tokens_for_voucher(voucher_value, public_key, unblinded_tokens) + retrieved_tokens = store.extract_unblinded_tokens(len(random_tokens)) + self.expectThat(unblinded_tokens, AfterPreprocessing(sorted, Equals(retrieved_tokens))) # After extraction, the unblinded tokens are no longer available. more_unblinded_tokens = store.extract_unblinded_tokens(1) -- GitLab