Ejemplo n.º 1
0
 def read_claim(self, claimkey, chain=None):
     if chain is None:
         try:
             value = self.state[claimkey.encode('utf-8')]
             return json.loads(value.decode('utf-8'))
         except KeyError:
             chain = self.chain
     try:
         with self.params.as_default():
             value = View(chain)[claimkey.encode('utf-8')]
             return json.loads(value.decode('utf-8'))
     except (KeyError, ValueError):
         return None
    def receive_message(self, sender, message_metadata, other_recipients=None):
        """
        Interpret incoming additional data

        :param sender: Sender identifier
        :param message_metadata: Additional data obtained by ``send_message``
        :param other_recipients: Identifiers of other known recipients of the
                                 message
        """
        logger.debug('%s <- %s', self.email, sender)
        if other_recipients is None:
            other_recipients = set()

        with self.params.as_default():
            # Merge stores temporarily.
            merged_store = ObjectStore(self.gossip_store)
            for key, obj in message_metadata.store.items():
                merged_store[key] = obj

            sender_head = message_metadata.head
            sender_latest_block = merged_store[sender_head]
            self.gossip_store[sender_head] = \
                    sender_latest_block
            self.expected_views[sender] = View(
                Chain(self.gossip_store, root_hash=sender_head))
            full_sender_view = View(Chain(merged_store, root_hash=sender_head))
            logger.debug('%s / expected view / %s', self.email, sender)

            # Add relevant objects from the message store.
            contacts = self.get_accessible_contacts(sender, message_metadata,
                                                    other_recipients)
            for contact in contacts - {self.email}:
                contact_head = self.get_contact_head_from_view(
                    full_sender_view, contact)
                if contact_head is None:
                    continue
                contact_latest_block = message_metadata.store.get(contact_head)
                if contact_latest_block is not None:
                    self.gossip_store[contact_head] = contact_latest_block

                # NOTE: Assumes people send only contacts' latest blocks
                contact_chain = Chain(self.gossip_store,
                                      root_hash=contact_head)
                self.global_views[sender][contact] = View(contact_chain)

            # TODO: Needs a special check for contact==self.email.

            # Recompute the latest beliefs.
            for contact in {sender} | contacts:
                self.get_latest_view(contact)
Ejemplo n.º 3
0
 def read_claim_from(self, chain, claimkey):
     assert callable(getattr(claimkey, 'encode', None))
     try:
         with self.params.as_default():
             return View(chain)[claimkey.encode('utf-8')].decode('utf-8')
     except (KeyError, ValueError):
         return None
Ejemplo n.º 4
0
 def register_peer(self, addr, root_hash, store_url, chain=None):
     # TODO: check for existing entries
     if not chain:
         chain = self.get_chain(store_url, root_hash)
     assert chain
     view = View(chain)
     pk = view.params.dh.pk
     assert pk
     self.add_claim((addr,
                     dict(root_hash=root_hash,
                          store_url=store_url,
                          public_key=pet2ascii(pk))))
Ejemplo n.º 5
0
def test_read_claim_from_other_chain():
    for i in range(1, 100):
        alice_params = LocalParams.generate()
        alice_state = State()
        alice_store = {}
        alice_chain = Chain(alice_store, None)
        alice_state.identity_info = "Hi, I'm " + pet2ascii(alice_params.dh.pk)
        with alice_params.as_default():
            alice_head = alice_state.commit(alice_chain)
        alice_chain = Chain(alice_store, alice_head)

        bob_params = LocalParams.generate()
        bob_state = State()
        bob_store = {}
        bob_chain = Chain(bob_store, None)
        bob_state.identity_info = "Hi, I'm " + pet2ascii(bob_params.dh.pk)
        with bob_params.as_default():
            bob_head = bob_state.commit(bob_chain)
        bob_chain = Chain(bob_store, bob_head)

        bob_pk = bob_params.dh.pk

        with alice_params.as_default():
            alice_state[b"bobs_key"] = b"123abc"
            alice_state.grant_access(bob_pk, [b"bobs_key"])
            alice_head = alice_state.commit(alice_chain)
        alice_chain = Chain(alice_store, alice_head)

        with alice_params.as_default():
            value = View(alice_chain)[b'bobs_key'].decode('utf-8')

        assert value == "123abc"

        with bob_params.as_default():
            value = View(alice_chain)[b'bobs_key'].decode('utf-8')

        assert value == "123abc"
Ejemplo n.º 6
0
 def process_incoming_gossip(self, addr2pagh, account_key, dec_msg):
     root_hash = dec_msg["GossipClaims"]
     store = FileStore(dec_msg["ChainStore"])
     peers_chain = Chain(store, root_hash=ascii2bytes(root_hash))
     assert peers_chain
     view = View(peers_chain)
     peers_pk = view.params.dh.pk
     assert peers_pk
     sender = parse_email_addr(dec_msg["From"])
     self.addr2root_hash[sender] = root_hash
     self.addr2pk[sender] = peers_pk
     recipients = get_target_emailadr(dec_msg)
     for recipient in recipients:
         pagh = addr2pagh[recipient]
         value = self.read_claim_from(peers_chain, recipient)
         if value:
             # for now we can only read claims about ourselves...
             # so if we get a value it must be our head imprint.
             assert value == bytes2ascii(pagh.keydata)
Ejemplo n.º 7
0
 def read_claim_as(self, other, claimkey):
     assert callable(getattr(claimkey, 'encode', None))
     print("read-claim-as", other, repr(claimkey))
     chain = self._get_current_chain()
     with other.params.as_default():
         return View(chain)[claimkey.encode('utf-8')].decode('utf-8')