Skip to content
Snippets Groups Projects
Commit 72fb060d authored by inso's avatar inso
Browse files

Add sigDate data to identity class

parent 91cdf944
Branches
Tags
No related merge requests found
...@@ -74,16 +74,15 @@ class IdentitiesRegistry: ...@@ -74,16 +74,15 @@ class IdentitiesRegistry:
for result in data['results']: for result in data['results']:
if result["pubkey"] == identity.pubkey: if result["pubkey"] == identity.pubkey:
uids = result['uids'] uids = result['uids']
identity_uid = ""
for uid_data in uids: for uid_data in uids:
if uid_data["meta"]["timestamp"] > timestamp: if uid_data["meta"]["timestamp"] > timestamp:
timestamp = uid_data["meta"]["timestamp"] identity.sigdate = uid_data["meta"]["timestamp"]
identity_uid = uid_data["uid"] identity.uid = uid_data["uid"]
identity.uid = identity_uid
identity.blockchain_state = BlockchainState.BUFFERED identity.blockchain_state = BlockchainState.BUFFERED
identity.local_state = LocalState.PARTIAL identity.local_state = LocalState.PARTIAL
timestamp = identity.sigdate
return identity return identity
except ValueError as e: except ValueError:
lookup_tries += 1 lookup_tries += 1
except asyncio.TimeoutError: except asyncio.TimeoutError:
lookup_tries += 1 lookup_tries += 1
...@@ -95,6 +94,13 @@ class IdentitiesRegistry: ...@@ -95,6 +94,13 @@ class IdentitiesRegistry:
@asyncio.coroutine @asyncio.coroutine
def future_find(self, pubkey, community): def future_find(self, pubkey, community):
"""
:param pubkey: The pubkey we look for
:param community: The community where we look for the identity
:return: The identity found
:rtype: cutecoin.core.registry.Identity
"""
if pubkey in self._identities(community): if pubkey in self._identities(community):
identity = self._identities(community)[pubkey] identity = self._identities(community)[pubkey]
else: else:
...@@ -103,9 +109,10 @@ class IdentitiesRegistry: ...@@ -103,9 +109,10 @@ class IdentitiesRegistry:
tries = 0 tries = 0
while tries < 3 and identity.local_state == LocalState.NOT_FOUND: while tries < 3 and identity.local_state == LocalState.NOT_FOUND:
try: try:
data = yield from community.bma_access.simple_request(bma.wot.CertifiersOf, data = yield from community.bma_access.simple_request(bma.blockchain.Membership,
req_args={'search': pubkey}) req_args={'search': pubkey})
identity.uid = data['uid'] identity.uid = data['uid']
identity.sigdate = data['sigDate']
identity.local_state = LocalState.PARTIAL identity.local_state = LocalState.PARTIAL
identity.blockchain_state = BlockchainState.VALIDATED identity.blockchain_state = BlockchainState.VALIDATED
except ValueError as e: except ValueError as e:
...@@ -122,34 +129,38 @@ class IdentitiesRegistry: ...@@ -122,34 +129,38 @@ class IdentitiesRegistry:
return identity return identity
return identity return identity
def from_handled_data(self, uid, pubkey, blockchain_state, community): def from_handled_data(self, uid, pubkey, sigdate, blockchain_state, community):
""" """
Get a person from a metadata dict. Get a person from a metadata dict.
A metadata dict has a 'text' key corresponding to the person uid, A metadata dict has a 'text' key corresponding to the person uid,
and a 'id' key corresponding to the person pubkey. and a 'id' key corresponding to the person pubkey.
:param dict metadata: The person metadata :param str uid: The person uid, also known as its uid on the network
:return: A new person if pubkey wasn't knwon, else the existing instance. :param str pubkey: The person pubkey
:param int sig_date: The date of signature of the self certification
:param LocalState local_state: The local status of the identity
:param cutecoin.core.Community community: The community from which we found data
:rtype: cutecoin.core.registry.Identity
""" """
identities = self._identities(community) identities = self._identities(community)
if pubkey in identities: if pubkey in identities:
if self._identities(community)[pubkey].blockchain_state == BlockchainState.NOT_FOUND: if identities[pubkey].blockchain_state == BlockchainState.NOT_FOUND:
self._identities(community)[pubkey].blockchain_state = blockchain_state identities[pubkey].blockchain_state = blockchain_state
elif self._identities(community)[pubkey].blockchain_state != BlockchainState.VALIDATED \ elif identities[pubkey].blockchain_state != BlockchainState.VALIDATED \
and blockchain_state == BlockchainState.VALIDATED: and blockchain_state == BlockchainState.VALIDATED:
self._identities(community)[pubkey].blockchain_state = blockchain_state identities[pubkey].blockchain_state = blockchain_state
if identities[pubkey].uid != uid:
identities[pubkey].uid = uid
# TODO: Random bug in ucoin makes the uid change without reason in requests answers if sigdate and identities[pubkey].sigdate != sigdate:
# https://github.com/ucoin-io/ucoin/issues/149 identities[pubkey].sigdate = sigdate
#if self._instances[pubkey].uid != uid:
# self._instances[pubkey].uid = uid
# self._instances[pubkey].inner_data_changed.emit("BlockchainState")
if self._identities(community)[pubkey].local_state == LocalState.NOT_FOUND: if identities[pubkey].local_state == LocalState.NOT_FOUND:
self._identities(community)[pubkey].local_state = LocalState.COMPLETED identities[pubkey].local_state = LocalState.COMPLETED
return self._identities(community)[pubkey] return identities[pubkey]
else: else:
identity = Identity.from_handled_data(uid, pubkey, blockchain_state) identity = Identity.from_handled_data(uid, pubkey, sigdate, blockchain_state)
self._identities(community)[pubkey] = identity self._identities(community)[pubkey] = identity
return identity return identity
...@@ -14,7 +14,7 @@ from ucoinpy.api import bma as bma ...@@ -14,7 +14,7 @@ from ucoinpy.api import bma as bma
from ucoinpy.api.bma import PROTOCOL_VERSION from ucoinpy.api.bma import PROTOCOL_VERSION
from ...tools.exceptions import Error, NoPeerAvailable,\ from ...tools.exceptions import Error, NoPeerAvailable,\
MembershipNotFoundError MembershipNotFoundError, LookupFailureError
from PyQt5.QtCore import QObject, pyqtSignal from PyQt5.QtCore import QObject, pyqtSignal
...@@ -49,28 +49,30 @@ class Identity(QObject): ...@@ -49,28 +49,30 @@ class Identity(QObject):
""" """
A person with a uid and a pubkey A person with a uid and a pubkey
""" """
def __init__(self, uid, pubkey, local_state, blockchain_state): def __init__(self, uid, pubkey, sigdate, local_state, blockchain_state):
""" """
Initializing a person object. Initializing a person object.
:param str uid: The person uid, also known as its uid on the network :param str uid: The identity uid, also known as its uid on the network
:param str pubkey: The person pubkey :param str pubkey: The identity pubkey
:parma int sig_date: The date of signature of the self certification
:param LocalState local_state: The local status of the identity :param LocalState local_state: The local status of the identity
:param BlockchainState blockchain_state: The blockchain status of the identity :param BlockchainState blockchain_state: The blockchain status of the identity
""" """
super().__init__() super().__init__()
self.uid = uid self.uid = uid
self.pubkey = pubkey self.pubkey = pubkey
self.sigdate = sigdate
self.local_state = local_state self.local_state = local_state
self.blockchain_state = blockchain_state self.blockchain_state = blockchain_state
@classmethod @classmethod
def empty(cls, pubkey): def empty(cls, pubkey):
return cls("", pubkey, LocalState.NOT_FOUND, BlockchainState.NOT_FOUND) return cls("", pubkey, None, LocalState.NOT_FOUND, BlockchainState.NOT_FOUND)
@classmethod @classmethod
def from_handled_data(cls, uid, pubkey, blockchain_state): def from_handled_data(cls, uid, pubkey, sigdate, blockchain_state):
return cls(uid, pubkey, LocalState.COMPLETED, blockchain_state) return cls(uid, pubkey, sigdate, LocalState.COMPLETED, blockchain_state)
@classmethod @classmethod
def from_json(cls, json_data): def from_json(cls, json_data):
...@@ -82,10 +84,11 @@ class Identity(QObject): ...@@ -82,10 +84,11 @@ class Identity(QObject):
""" """
pubkey = json_data['pubkey'] pubkey = json_data['pubkey']
uid = json_data['uid'] uid = json_data['uid']
sigdate = json_data['sigdate']
local_state = LocalState[json_data['local_state']] local_state = LocalState[json_data['local_state']]
blockchain_state = BlockchainState[json_data['blockchain_state']] blockchain_state = BlockchainState[json_data['blockchain_state']]
return cls(uid, pubkey, local_state, blockchain_state) return cls(uid, pubkey, sigdate, local_state, blockchain_state)
@asyncio.coroutine @asyncio.coroutine
def selfcert(self, community): def selfcert(self, community):
...@@ -97,24 +100,40 @@ class Identity(QObject): ...@@ -97,24 +100,40 @@ class Identity(QObject):
:return: A SelfCertification ucoinpy object :return: A SelfCertification ucoinpy object
:rtype: ucoinpy.documents.certification.SelfCertification :rtype: ucoinpy.documents.certification.SelfCertification
""" """
try:
timestamp = 0 timestamp = 0
lookup_data = yield from community.bma_access.future_request(bma.wot.Lookup, req_args={'search': self.pubkey}) lookup_data = yield from community.bma_access.future_request(bma.wot.Lookup,
req_args={'search': self.pubkey})
for result in lookup_data['results']: for result in lookup_data['results']:
if result["pubkey"] == self.pubkey: if result["pubkey"] == self.pubkey:
uids = result['uids'] uids = result['uids']
for uid_data in uids: for uid_data in uids:
if uid_data["meta"]["timestamp"] > timestamp: # If we sigDate was written in the blockchain
if self.sigdate and uid_data["meta"]["timestamp"] == self.sigdate:
timestamp = uid_data["meta"]["timestamp"]
uid = uid_data["uid"]
signature = uid_data["self"]
# Else we choose the latest one found
elif uid_data["meta"]["timestamp"] > timestamp:
timestamp = uid_data["meta"]["timestamp"] timestamp = uid_data["meta"]["timestamp"]
uid = uid_data["uid"] uid = uid_data["uid"]
signature = uid_data["self"] signature = uid_data["self"]
if not self.sigdate:
self.sigdate = timestamp
return SelfCertification(PROTOCOL_VERSION, return SelfCertification(PROTOCOL_VERSION,
community.currency, community.currency,
self.pubkey, self.pubkey,
timestamp, timestamp,
uid, uid,
signature) signature)
return None except ValueError as e:
if '404' in str(e):
raise LookupFailureError(self.pubkey, community)
except NoPeerAvailable:
logging.debug("No peer available")
@asyncio.coroutine @asyncio.coroutine
def get_join_date(self, community): def get_join_date(self, community):
...@@ -177,6 +196,9 @@ class Identity(QObject): ...@@ -177,6 +196,9 @@ class Identity(QObject):
{'search': self.pubkey}) {'search': self.pubkey})
block_number = -1 block_number = -1
membership_data = None membership_data = None
#TODO: Should not be here, should be set when we look for the identity
#We do it because we do not have this info in certifiers-of yet...
self.sigdate = search['sigDate']
for ms in search['memberships']: for ms in search['memberships']:
if ms['blockNumber'] > block_number: if ms['blockNumber'] > block_number:
block_number = ms['blockNumber'] block_number = ms['blockNumber']
...@@ -273,6 +295,7 @@ class Identity(QObject): ...@@ -273,6 +295,7 @@ class Identity(QObject):
certifier = {} certifier = {}
certifier['identity'] = identities_registry.from_handled_data(certifier_data['uid'], certifier['identity'] = identities_registry.from_handled_data(certifier_data['uid'],
certifier_data['pubkey'], certifier_data['pubkey'],
None,
BlockchainState.VALIDATED, BlockchainState.VALIDATED,
community) community)
certifier['cert_time'] = certifier_data['cert_time']['medianTime'] certifier['cert_time'] = certifier_data['cert_time']['medianTime']
...@@ -303,6 +326,7 @@ class Identity(QObject): ...@@ -303,6 +326,7 @@ class Identity(QObject):
certifier['identity'] = identities_registry.\ certifier['identity'] = identities_registry.\
from_handled_data(uid, from_handled_data(uid,
certifier_data['pubkey'], certifier_data['pubkey'],
None,
BlockchainState.BUFFERED, BlockchainState.BUFFERED,
community) community)
block = yield from community.bma_access.future_request(bma.blockchain.Block, block = yield from community.bma_access.future_request(bma.blockchain.Block,
...@@ -367,6 +391,7 @@ class Identity(QObject): ...@@ -367,6 +391,7 @@ class Identity(QObject):
certified = {} certified = {}
certified['identity'] = identities_registry.from_handled_data(certified_data['uid'], certified['identity'] = identities_registry.from_handled_data(certified_data['uid'],
certified_data['pubkey'], certified_data['pubkey'],
None,
BlockchainState.VALIDATED, BlockchainState.VALIDATED,
community) community)
certified['cert_time'] = certified_data['cert_time']['medianTime'] certified['cert_time'] = certified_data['cert_time']['medianTime']
...@@ -390,6 +415,7 @@ class Identity(QObject): ...@@ -390,6 +415,7 @@ class Identity(QObject):
certified = {} certified = {}
certified['identity'] = identities_registry.from_handled_data(certified_data['uid'], certified['identity'] = identities_registry.from_handled_data(certified_data['uid'],
certified_data['pubkey'], certified_data['pubkey'],
None,
BlockchainState.BUFFERED, BlockchainState.BUFFERED,
community) community)
certified['cert_time'] = certified_data['meta']['timestamp'] certified['cert_time'] = certified_data['meta']['timestamp']
...@@ -459,12 +485,14 @@ class Identity(QObject): ...@@ -459,12 +485,14 @@ class Identity(QObject):
""" """
data = {'uid': self.uid, data = {'uid': self.uid,
'pubkey': self.pubkey, 'pubkey': self.pubkey,
'sigdate': self.sigdate,
'local_state': self.local_state.name, 'local_state': self.local_state.name,
'blockchain_state': self.blockchain_state.name} 'blockchain_state': self.blockchain_state.name}
return data return data
def __str__(self): def __str__(self):
return "{0} - {1} - {2} - {3}".format(self.uid, return "{uid} - {pubkey} - {sigdate} - {local} - {blockchain}".format(uid=self.uid,
self.pubkey, pubkey=self.pubkey,
self.local_state, sigdate=self.sigdate,
self.blockchain_state) local=self.local_state,
blockchain=self.blockchain_state)
...@@ -20,7 +20,7 @@ from .member import MemberDialog ...@@ -20,7 +20,7 @@ from .member import MemberDialog
from .transfer import TransferMoneyDialog from .transfer import TransferMoneyDialog
from cutecoin.gui.widgets.busy import Busy from cutecoin.gui.widgets.busy import Busy
from .certification import CertificationDialog from .certification import CertificationDialog
from ..core.registry import Identity from ..core.registry import Identity, BlockchainState
from ..tools.exceptions import NoPeerAvailable from ..tools.exceptions import NoPeerAvailable
from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
...@@ -210,7 +210,11 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab): ...@@ -210,7 +210,11 @@ class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
response = yield from self.community.bma_access.future_request(bma.wot.Lookup, {'search': text}) response = yield from self.community.bma_access.future_request(bma.wot.Lookup, {'search': text})
identities = [] identities = []
for identity_data in response['results']: for identity_data in response['results']:
identity = yield from self.app.identities_registry.future_find(identity_data['pubkey'], self.community) for uid_data in identity_data['uids']:
identity = Identity.from_handled_data(uid_data['uid'],
identity_data['pubkey'],
uid_data['meta']['timestamp'],
BlockchainState.BUFFERED)
identities.append(identity) identities.append(identity)
self.edit_textsearch.clear() self.edit_textsearch.clear()
......
...@@ -52,8 +52,9 @@ class IdentitiesFilterProxyModel(QSortFilterProxyModel): ...@@ -52,8 +52,9 @@ class IdentitiesFilterProxyModel(QSortFilterProxyModel):
if expiration_data is not None: if expiration_data is not None:
will_expire_soon = (current_time > expiration_data*1000 - warning_expiration_time*1000) will_expire_soon = (current_time > expiration_data*1000 - warning_expiration_time*1000)
if role == Qt.DisplayRole: if role == Qt.DisplayRole:
if source_index.column() == self.sourceModel().columns_ids.index('renewed') \ if source_index.column() in (self.sourceModel().columns_ids.index('renewed'),
or source_index.column() == self.sourceModel().columns_ids.index('expiration'): self.sourceModel().columns_ids.index('expiration'),
self.sourceModel().columns_ids.index('publication')):
if source_data is not None: if source_data is not None:
return QLocale.toString( return QLocale.toString(
QLocale(), QLocale(),
...@@ -90,8 +91,9 @@ class IdentitiesTableModel(QAbstractTableModel): ...@@ -90,8 +91,9 @@ class IdentitiesTableModel(QAbstractTableModel):
'pubkey': self.tr('Pubkey'), 'pubkey': self.tr('Pubkey'),
'renewed': self.tr('Renewed'), 'renewed': self.tr('Renewed'),
'expiration': self.tr('Expiration'), 'expiration': self.tr('Expiration'),
'validation': self.tr('Validation')} 'publication': self.tr('Publication'),
self.columns_ids = ('uid', 'pubkey', 'renewed', 'expiration') 'validation': self.tr('Validation'),}
self.columns_ids = ('uid', 'pubkey', 'renewed', 'expiration', 'publication')
self.identities_data = [] self.identities_data = []
self._sig_validity = 0 self._sig_validity = 0
...@@ -126,7 +128,7 @@ class IdentitiesTableModel(QAbstractTableModel): ...@@ -126,7 +128,7 @@ class IdentitiesTableModel(QAbstractTableModel):
join_date = None join_date = None
expiration_date = None expiration_date = None
return identity.uid, identity.pubkey, join_date, expiration_date return identity.uid, identity.pubkey, join_date, expiration_date, identity.sigdate
@asyncio.coroutine @asyncio.coroutine
def refresh_identities(self, identities): def refresh_identities(self, identities):
......
...@@ -26,7 +26,7 @@ class TestIdentity(unittest.TestCase): ...@@ -26,7 +26,7 @@ class TestIdentity(unittest.TestCase):
community = mock.MagicMock() community = mock.MagicMock()
type(community).currency = mock.PropertyMock(return_value="test_currency") type(community).currency = mock.PropertyMock(return_value="test_currency")
identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", None,
LocalState.COMPLETED, BlockchainState.VALIDATED) LocalState.COMPLETED, BlockchainState.VALIDATED)
test_instances = { test_instances = {
"test_currency": {"7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ": identity} "test_currency": {"7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ": identity}
...@@ -34,7 +34,9 @@ class TestIdentity(unittest.TestCase): ...@@ -34,7 +34,9 @@ class TestIdentity(unittest.TestCase):
identities_registry = IdentitiesRegistry(test_instances) identities_registry = IdentitiesRegistry(test_instances)
identity_from_data = identities_registry.from_handled_data("john", identity_from_data = identities_registry.from_handled_data("john",
"7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", BlockchainState.VALIDATED, "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
None,
BlockchainState.VALIDATED,
community) community)
self.assertEqual(identity, identity_from_data) self.assertEqual(identity, identity_from_data)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment