Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merkle proof update for web batch #121

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion app.py
Expand Up @@ -26,4 +26,4 @@ def issue():
return json.dumps(certificate_batch_handler.proof)

if __name__ == '__main__':
app.run()
app.run(host='0.0.0.0')
12 changes: 8 additions & 4 deletions cert_issuer/certificate_handlers.py
Expand Up @@ -9,7 +9,6 @@

from cert_issuer.signer import FinalizableSigner


class CertificateV2Handler(CertificateHandler):
def get_byte_array_to_issue(self, certificate_metadata):
certificate_json = self._get_certificate_to_issue(certificate_metadata)
Expand Down Expand Up @@ -44,11 +43,16 @@ def add_proof(self, certificate_json, merkle_proof):
:param merkle_proof:
:return:
"""
return merkle_proof
certificate_json['signature'] = merkle_proof
return certificate_json

class CertificateBatchWebHandler(BatchHandler):
def finish_batch(self, tx_id, chain):
self.proof = next(self.merkle_tree.get_proof_generator(tx_id, chain))
self.proof = []
proof_generator = self.merkle_tree.get_proof_generator(tx_id, chain)
for metadata in self.certificates_to_issue:
proof = next(proof_generator)
self.proof.append(self.certificate_handler.add_proof(metadata, proof))

def get_certificate_generator(self):
"""
Expand Down Expand Up @@ -117,7 +121,7 @@ def get_certificate_generator(self):

def finish_batch(self, tx_id, chain):
proof_generator = self.merkle_tree.get_proof_generator(tx_id, chain)
for uid, metadata in self.certificates_to_issue.items():
for metadata in self.certificates_to_issue.items():
proof = next(proof_generator)
self.certificate_handler.add_proof(metadata, proof)

Expand Down
146 changes: 124 additions & 22 deletions tests/test_certificate_handler.py
Expand Up @@ -2,14 +2,68 @@

import mock
import json
import io
from pycoin.serialize import b2h
from unittest.mock import patch
from mock import patch, mock_open

from cert_issuer.certificate_handlers import CertificateBatchHandler, CertificateHandler, CertificateBatchWebHandler
from cert_issuer.certificate_handlers import CertificateWebV2Handler, CertificateV2Handler, CertificateBatchHandler, CertificateHandler, CertificateBatchWebHandler
from cert_issuer.merkle_tree_generator import MerkleTreeGenerator
from cert_issuer import helpers
from mock import ANY

class TestCertificateHandler(unittest.TestCase):
def _proof_helper(self, chain):
proof = {
'merkleRoot': '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044',
'type': ['MerkleProof2017', 'Extension'],
'targetHash': ANY,
'anchors': [
{
'sourceId': ANY,
'type': chain.blockchain_type.external_display_value,
'chain': chain.external_display_value
}
],
'proof': [
{'right': 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35'},
{'right': '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce'}
],
}

proof_1 = {
'merkleRoot': '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044',
'type': ['MerkleProof2017', 'Extension'],
'targetHash': ANY,
'anchors': [
{
'sourceId': ANY,
'type': chain.blockchain_type.external_display_value,
'chain': chain.external_display_value
}
],
'proof': [
{'left': '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b'},
{'right': '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce'}
]
}

proof_2 = {
'merkleRoot': '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044',
'type': ['MerkleProof2017', 'Extension'],
'targetHash': ANY,
'anchors': [
{
'sourceId': ANY,
'type': chain.blockchain_type.external_display_value,
'chain': chain.external_display_value
}
],
'proof': [
{'left': '4295f72eeb1e3507b8461e240e3b8d18c1e7bd2f1122b11fc9ec40a65894031a'}
]
}
return proof, proof_1, proof_2

def _helper_mock_call(self, *args):
helper_mock = mock.MagicMock()
helper_mock.__len__.return_value = self.directory_count
Expand All @@ -36,7 +90,6 @@ def _get_certificate_batch_web_handler(self):

return handler, certificates_to_issue


def _get_certificate_batch_handler(self):
secret_manager = mock.Mock()
certificates_to_issue = dict()
Expand All @@ -51,37 +104,57 @@ def _get_certificate_batch_handler(self):

return handler, certificates_to_issue

def test_batch_handler_web_prepare(self):
web_request = json.dumps([{'allyourbasearebelongtous': True}])
def test_batch_handler_web_prepare_batch(self):
web_handler, certificates_to_issue = self._get_certificate_batch_web_handler()
web_handler.set_certificates_in_batch(web_request)
single_item_batch = web_handler.prepare_batch()

web_handler.set_certificates_in_batch(certificates_to_issue)
result = web_handler.prepare_batch()
self.assertEqual(
b2h(single_item_batch),
'38451f557bc2b5ad74012d3389798281b993fc7375c024615ed73fb147670ba7')
b2h(result), '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044')

web_handler, certificates_to_issue = self._get_certificate_batch_web_handler()
web_handler.set_certificates_in_batch(
[{'allyourbasearebelongtous': True}, {'allyourbasearebelongtous': False}])
multi_batch = web_handler.prepare_batch()
self.assertNotEqual(b2h(single_item_batch), b2h(multi_batch))
def test_batch_handler_prepare_batch(self):
certificate_batch_handler, certificates_to_issue = self._get_certificate_batch_handler()

certificate_batch_handler.set_certificates_in_batch(certificates_to_issue)
result = certificate_batch_handler.prepare_batch()
self.assertEqual(
b2h(result), '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044')

def test_batch_handler_prepare_batch(self):
secret_manager = mock.Mock()
certificates_to_issue = dict()
certificates_to_issue['1'] = mock.Mock()
certificates_to_issue['2'] = mock.Mock()
certificates_to_issue['3'] = mock.Mock()
def test_batch_web_handler_finish_batch(self):
certificate_batch_handler, certificates_to_issue = self._get_certificate_batch_web_handler()

certificate_batch_handler.set_certificates_in_batch(certificates_to_issue)
result = certificate_batch_handler.prepare_batch()

chain = mock.Mock()
proof, proof_1, proof_2 = self._proof_helper(chain)

with patch.object(DummyCertificateHandler, 'add_proof', return_value= {"cert": "cert"} ) as mock_method:
result = certificate_batch_handler.finish_batch(
'5604f0c442922b5db54b69f8f363b3eac67835d36a006b98e8727f83b6a830c0', chain
)
self.assertEqual(certificate_batch_handler.proof, [{'cert': 'cert'}, {'cert': 'cert'}, {'cert': 'cert'}])
mock_method.assert_any_call(ANY, proof)
mock_method.assert_any_call(ANY, proof_1)
mock_method.assert_any_call(ANY, proof_2)

def test_batch_handler_finish_batch(self):
certificate_batch_handler, certificates_to_issue = self._get_certificate_batch_handler()

certificate_batch_handler.set_certificates_in_batch(certificates_to_issue)
result = certificate_batch_handler.prepare_batch()

self.assertEqual(
b2h(result), '0932f1d2e98219f7d7452801e2b64ebd9e5c005539db12d9b1ddabe7834d9044')
chain = mock.Mock()
proof, proof_1, proof_2 = self._proof_helper(chain)

with patch.object(DummyCertificateHandler, 'add_proof') as mock_method:
result = certificate_batch_handler.finish_batch(
'5604f0c442922b5db54b69f8f363b3eac67835d36a006b98e8727f83b6a830c0', chain
)

mock_method.assert_any_call(ANY, proof)
mock_method.assert_any_call(ANY, proof_1)
mock_method.assert_any_call(ANY, proof_2)

def test_pre_batch_actions(self):
self.directory_count = 1
Expand Down Expand Up @@ -121,6 +194,35 @@ def test_pre_batch_actions_empty_directories(self):

assert not mock_method.called

@mock.patch("__builtin__.open", create=True)
def test_add_proof(self,mock_open):
handler = CertificateV2Handler()

cert_to_issue = {'kek':'kek'}
proof = {'a': 'merkel'}
file_call = 'call().__enter__().write(\'{"kek": "kek", "signature": {"a": "merkel"}}\')'

chain = mock.Mock()
metadata = mock.Mock()
metadata.blockchain_cert_file_name = 'file_path.nfo'

with patch.object(
CertificateV2Handler, '_get_certificate_to_issue', return_value=cert_to_issue) as mock_method:
handler.add_proof(metadata, proof)

mock_open.assert_any_call('file_path.nfo','w')
calls = mock_open.mock_calls
call_strings = map(str, calls)
assert file_call in call_strings

def test_web_add_proof(self):
handler = CertificateWebV2Handler()
proof = {'a': 'merkel'}
chain = mock.Mock()
certificate_json = {'kek': 'kek'}

return_cert = handler.add_proof(certificate_json, proof)
self.assertEqual(return_cert, {'kek':'kek', 'signature': {'a': 'merkel'}})

class DummyCertificateHandler(CertificateHandler):
def __init__(self):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_signer.py
@@ -1,5 +1,5 @@
import unittest
from unittest import mock
import mock

from cert_issuer.signer import FinalizableSigner

Expand Down
11 changes: 11 additions & 0 deletions wsgi.ini
@@ -0,0 +1,11 @@
[uwsgi]
module = wsgi:app
master = true
processes = 5

socket = 127.0.0.1:5000
chmod-socket = 660
vacuum = true
plugin = python36

die-on-term = true
4 changes: 4 additions & 0 deletions wsgi.py
@@ -0,0 +1,4 @@
from app import app

if __name__ == "__main__":
app.run()