Coverage for silkaj/wot/idty_tools.py: 100%
77 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-17 17:03 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-17 17:03 +0000
1# Copyright 2016-2024 Maël Azimi <m.a@moul.re>
2#
3# Silkaj is free software: you can redistribute it and/or modify
4# it under the terms of the GNU Affero General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7#
8# Silkaj is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU Affero General Public License for more details.
12#
13# You should have received a copy of the GNU Affero General Public License
14# along with Silkaj. If not, see <https://www.gnu.org/licenses/>.
16import shutil
17import sys
18import urllib
19from typing import List, Union
21import pendulum
22import rich_click as click
23from duniterpy.api import bma
24from duniterpy.documents import BlockID, Identity, Revocation
25from texttable import Texttable
27from silkaj.constants import ALL
28from silkaj.network import client_instance
29from silkaj.public_key import gen_pubkey_checksum
30from silkaj.wot.tools import wot_lookup
33def display_identity(idty: Identity) -> Texttable:
34 """
35 Creates a table containing the identity infos
36 """
37 client = client_instance()
38 id_table = []
39 id_table.append(["Public key", gen_pubkey_checksum(idty.pubkey)])
40 id_table.append(["User ID", idty.uid])
41 id_table.append(["Blockstamp", str(idty.block_id)])
42 creation_block = client(bma.blockchain.block, idty.block_id.number)
43 creation_date = pendulum.from_timestamp(creation_block["time"], tz="local").format(
44 ALL,
45 )
46 id_table.append(["Created on", creation_date])
47 # display infos
48 table = Texttable(max_width=shutil.get_terminal_size().columns)
49 table.add_rows(id_table, header=False)
50 return table
53def check_many_identities(document: Union[Identity, Revocation]) -> bool:
54 """
55 Checks if many identities match the one looked after.
56 Returns True if the same identity is found, False if not.
57 """
58 doc_type = document.__class__.__name__
59 error_no_identical_id = f"{doc_type} document does not match any valid identity."
60 idty = document if doc_type == "Identity" else document.identity
62 try:
63 results_pubkey = wot_lookup(idty.pubkey)
64 results_uid = wot_lookup(idty.uid)
65 except urllib.error.HTTPError:
66 sys.exit(
67 f"{error_no_identical_id}\nuid: {idty.uid} \
68 \npubkey: \
69{gen_pubkey_checksum(idty.pubkey)}",
70 )
72 # get all matching identities
73 lookup_ids = merge_ids_lists(results_pubkey, results_uid, idty.currency)
74 match = False
75 for n, lookup in enumerate(lookup_ids):
76 if idty == lookup:
77 lookup_ids.pop(n)
78 match = True
79 break
80 alternate_ids = display_alternate_ids(lookup_ids).draw()
81 if match:
82 if len(lookup_ids) >= 1:
83 click.echo(f"One matching identity!\nSimilar identities:\n{alternate_ids}")
84 return True
85 click.echo(f"{error_no_identical_id}\nSimilar identities:\n{alternate_ids}")
86 return False
89def display_alternate_ids(ids_list: List) -> Texttable:
90 labels = ["uid", "public key", "timestamp"]
91 table = Texttable(max_width=shutil.get_terminal_size().columns)
92 table.header(labels)
93 for _id in ids_list:
94 table.add_row(
95 [_id.uid, gen_pubkey_checksum(_id.pubkey), str(_id.block_id)[:12]],
96 )
97 return table
100def merge_ids_lists(lookups_pubkey: List, lookups_uid: List, currency: str) -> List:
101 """
102 merge two lists of identities and remove duplicate identities.
103 """
104 ids = ids_list_from_lookups(lookups_pubkey, currency)
105 ids_uid = ids_list_from_lookups(lookups_uid, currency)
106 for _id in ids_uid:
107 # __equal__ does not work. This is condition "id in ids".
108 for listed_id in ids:
109 if _id.signed_raw() == listed_id.signed_raw():
110 id_in_ids = True
111 break
112 id_in_ids = False
113 if not id_in_ids:
114 ids.append(_id)
115 return ids
118def ids_list_from_lookups(lookups: List, currency: str) -> List:
119 ids = []
120 for lookup in lookups:
121 pubkey = lookup["pubkey"]
122 lookup_ids = lookup["uids"]
123 for _id in lookup_ids:
124 appended_id = Identity(
125 currency=currency,
126 pubkey=pubkey,
127 uid=_id["uid"],
128 block_id=BlockID.from_str(_id["meta"]["timestamp"]),
129 )
130 appended_id.signature = _id["self"]
131 ids.append(appended_id)
132 return ids