regen constants and improve high level API for QR setup contact

This commit is contained in:
holger krekel
2019-09-04 20:21:46 +02:00
parent 2920732435
commit b6997c4455
3 changed files with 58 additions and 16 deletions

View File

@@ -330,20 +330,35 @@ class Account(object):
return from_dc_charpointer(res)
def get_setup_contact_qr(self):
""" get/Create Setup-Contact QR Code as ascii-string """
""" get/create Setup-Contact QR Code as ascii-string.
this string needs to be transferred to another DC account
in a second channel (typically used by mobiles with QRcode-show + scan UX)
where setup_secure_contact(qr) is called.
"""
res = lib.dc_get_securejoin_qr(self._dc_context, 0)
return from_dc_charpointer(res)
def check_qr(self, qr):
""" check qr code ..."""
""" check qr code and return :class:`ScannedQRCode` instance representing the result"""
res = ffi.gc(
lib.dc_check_qr(self._dc_context, as_dc_charpointer(qr)),
lib.dc_lot_unref
)
return DCLot(res)
lot = DCLot(res)
if lot.state() == const.DC_QR_ERROR:
raise ValueError("invalid or unknown QR code: {}".format(lot.text1()))
return ScannedQRCode(lot)
def setup_secure_contact(self, qr):
""" """
""" setup secure contact and return a channel after contact is established.
Note that this function may block for a long time as messages are exchanged
with the emitter of the QR code. On success a :class:`deltachat.chatting.Chat` instance
is returned.
:param qr: valid "setup contact" QR code (all other QR codes will result in an exception)
"""
assert self.check_qr(qr).is_ask_verifycontact()
chat_id = lib.dc_join_securejoin(self._dc_context, as_dc_charpointer(qr))
if chat_id == 0:
raise ValueError("could not setup secure contact")
@@ -512,3 +527,18 @@ def _destroy_dc_context(dc_context, dc_context_unref=lib.dc_context_unref):
# we are deep into Python Interpreter shutdown,
# so no need to clear the callback context mapping.
pass
class ScannedQRCode:
def __init__(self, dc_lot):
self._dc_lot = dc_lot
def is_ask_verifycontact(self):
return self._dc_lot.state() == const.DC_QR_ASK_VERIFYCONTACT
def is_ask_verifygroup(self):
return self._dc_lot.state() == const.DC_QR_ASK_VERIFYGROUP
@property
def contact_id(self):
return self._dc_lot.id()

View File

@@ -13,6 +13,15 @@ DC_GCL_NO_SPECIALS = 0x02
DC_GCL_ADD_ALLDONE_HINT = 0x04
DC_GCL_VERIFIED_ONLY = 0x01
DC_GCL_ADD_SELF = 0x02
DC_QR_ASK_VERIFYCONTACT = 200
DC_QR_ASK_VERIFYGROUP = 202
DC_QR_FPR_OK = 210
DC_QR_FPR_MISMATCH = 220
DC_QR_FPR_WITHOUT_ADDR = 230
DC_QR_ADDR = 320
DC_QR_TEXT = 330
DC_QR_URL = 332
DC_QR_ERROR = 400
DC_CHAT_ID_DEADDROP = 1
DC_CHAT_ID_TRASH = 3
DC_CHAT_ID_MSGS_IN_CREATION = 4
@@ -69,15 +78,13 @@ DC_EVENT_IMEX_FILE_WRITTEN = 2052
DC_EVENT_SECUREJOIN_INVITER_PROGRESS = 2060
DC_EVENT_SECUREJOIN_JOINER_PROGRESS = 2061
DC_EVENT_GET_STRING = 2091
DC_EVENT_HTTP_GET = 2100
DC_EVENT_HTTP_POST = 2110
DC_EVENT_FILE_COPIED = 2055
DC_EVENT_IS_OFFLINE = 2081
# end const generated
def read_event_defines(f):
rex = re.compile(r'#define\s+((?:DC_EVENT_|DC_MSG|DC_STATE_|DC_CONTACT_ID_|DC_GCL|DC_CHAT)\S+)\s+([x\d]+).*')
rex = re.compile(r'#define\s+((?:DC_EVENT_|DC_QR|DC_MSG|DC_STATE_|DC_CONTACT_ID_|DC_GCL|DC_CHAT)\S+)\s+([x\d]+).*')
for line in f:
m = rex.match(line)
if m:
@@ -90,7 +97,7 @@ if __name__ == "__main__":
if len(sys.argv) >= 2:
deltah = sys.argv[1]
else:
deltah = joinpath(dirname(dirname(dirname(here_dir))), "src", "deltachat.h")
deltah = joinpath(dirname(dirname(dirname(here_dir))), "deltachat-ffi", "deltachat.h")
assert os.path.exists(deltah)
lines = []

View File

@@ -306,6 +306,19 @@ class TestOfflineChat:
chat1.set_draft(None)
assert chat1.get_draft() is None
def test_setup_contact(self, acfactory, lp):
# note that the receiving account needs to be configured and running
# before ther setup message is send. DC does not read old messages
# as of Jul2019
ac1 = acfactory.get_configured_offline_account()
ac2 = acfactory.get_configured_offline_account()
qr = ac1.get_setup_contact_qr()
assert qr.startswith("OPENPGP4FPR:")
res = ac2.check_qr(qr)
assert res.is_ask_verifycontact()
assert not res.is_ask_verifygroup()
assert res.contact_id == 10
class TestOnlineAccount:
def test_one_account_init(self, acfactory):
@@ -548,9 +561,6 @@ class TestOnlineAccount:
assert ac1.get_info()["fingerprint"] == ac2.get_info()["fingerprint"]
def test_setup_contact(self, acfactory, lp):
# note that the receiving account needs to be configured and running
# before ther setup message is send. DC does not read old messages
# as of Jul2019
ac1 = acfactory.get_online_configuring_account()
ac2 = acfactory.get_online_configuring_account()
wait_configuration_progress(ac2, 1000)
@@ -559,11 +569,6 @@ class TestOnlineAccount:
qr = ac1.get_setup_contact_qr()
assert qr.startswith("OPENPGP4FPR:")
res = ac2.check_qr(qr)
assert res.state() == 200
assert res.id() == 10
lp.sec("ac2: start QR-code based setup contact protocol")
ch = ac2.setup_secure_contact(qr)
assert ch.id >= 10