From 2a6343b72c1f9d511f4b31ab252319ce10c3e82f Mon Sep 17 00:00:00 2001 From: Edouard Tisserant Date: Fri, 18 Nov 2016 00:11:30 +0100 Subject: [PATCH] Added flags to Identity constructor, set_identity_flags, unset_identity_flags. Added support for pEp enums through boost enums<>, reflected in tests. Switched MultiProcess Sync test from fork to spawn, to work around problems when loading pEp module from main process before forking child processes. Fixed temp dir being destroyed in case of exception, preventing post-mortem analysis of management DB. --- src/basic_api.cc | 22 ++++++++++++++++++++++ src/basic_api.hh | 3 +++ src/identity.cc | 3 ++- src/identity.hh | 2 +- src/pEpmodule.cc | 40 +++++++++++++++++++++++++++++++++++++--- test/mp_sync_test.py | 20 ++++++++++---------- test/multipEp.py | 41 +++++++++++++++++++---------------------- 7 files changed, 94 insertions(+), 37 deletions(-) diff --git a/src/basic_api.cc b/src/basic_api.cc index 4195eac..27ab164 100644 --- a/src/basic_api.cc +++ b/src/basic_api.cc @@ -74,6 +74,28 @@ namespace pEp { PEP_STATUS status = trust_personal_key(session, ident); _throw_status(status); } + + void set_identity_flags(Identity ident, identity_flags_t flags) + { + if (ident.address() == "") + throw invalid_argument("address needed"); + if (ident.user_id() == "") + throw invalid_argument("user_id needed"); + + PEP_STATUS status = set_identity_flags(session, ident, flags); + _throw_status(status); + } + + void unset_identity_flags(Identity ident, identity_flags_t flags) + { + if (ident.address() == "") + throw invalid_argument("address needed"); + if (ident.user_id() == "") + throw invalid_argument("user_id needed"); + + PEP_STATUS status = unset_identity_flags(session, ident, flags); + _throw_status(status); + } } } diff --git a/src/basic_api.hh b/src/basic_api.hh index efc4a91..a3d90e0 100644 --- a/src/basic_api.hh +++ b/src/basic_api.hh @@ -8,6 +8,9 @@ namespace pEp { void myself(Identity& ident); string _trustwords(Identity me, Identity partner, string lang); void trust_personal_key(Identity ident); + + void set_identity_flags(Identity ident, identity_flags_t flags); + void unset_identity_flags(Identity ident, identity_flags_t flags); } } diff --git a/src/identity.cc b/src/identity.cc index 86f2ada..0b83ee8 100644 --- a/src/identity.cc +++ b/src/identity.cc @@ -12,13 +12,14 @@ namespace pEp { using namespace std; Identity::Identity(string address, string username, string user_id, - string fpr, int comm_type, string lang) + string fpr, int comm_type, string lang, identity_flags_t flags) : _ident(new_identity(address.c_str(), fpr.c_str(), user_id.c_str(), username.c_str()), &::free_identity) { if (!_ident) throw bad_alloc(); _ident->comm_type = (PEP_comm_type) comm_type; + _ident->flags = (identity_flags_t) flags; this->lang(lang); } diff --git a/src/identity.hh b/src/identity.hh index fa427ea..0eaf70e 100644 --- a/src/identity.hh +++ b/src/identity.hh @@ -20,7 +20,7 @@ namespace pEp { public: Identity(string address = "", string username = "", string user_id = "", string fpr = "", int comm_type = 0, - string lang = ""); + string lang = "", identity_flags_t flags = 0); Identity(const Identity& second); Identity(pEp_identity *ident); diff --git a/src/pEpmodule.cc b/src/pEpmodule.cc index 85beb09..de7db9b 100644 --- a/src/pEpmodule.cc +++ b/src/pEpmodule.cc @@ -7,6 +7,8 @@ #include "message_api.hh" #include "sync_mixin.hh" +#include + namespace pEp { namespace PythonAdapter { using namespace std; @@ -266,26 +268,58 @@ BOOST_PYTHON_MODULE(pEp) // basic API - def("update_identity", &update_identity, + def("update_identity", &pEp::PythonAdapter::update_identity, "update_identity(ident)\n" "\n" "update identity information\n" "call this to complete identity information when you at least have an address\n" ); - def("myself", &myself, + def("myself", &pEp::PythonAdapter::myself, "myself(ident)\n" "\n" "ensures that the own identity is being complete\n" "supply ident.address and ident.username\n" ); - def("trust_personal_key", &trust_personal_key, + def("trust_personal_key", &pEp::PythonAdapter::trust_personal_key, "trust_personal_key(ident)\n" "\n" "mark a key as trusted with a person\n" ); + enum_("identity_flags") + .value("PEP_idf_not_for_sync", PEP_idf_not_for_sync) + .value("PEP_idf_list", PEP_idf_list) + .value("PEP_idf_devicegroup", PEP_idf_devicegroup); + + def("set_identity_flags", &pEp::PythonAdapter::set_identity_flags, + "set_identity_flags(ident, flags)\n" + "\n" + "set identity flags\n" + ); + + def("unset_identity_flags", &pEp::PythonAdapter::unset_identity_flags, + "unset_identity_flags(ident, flags)\n" + "\n" + "unset identity flags\n" + ); + // message API + enum_("PEP_rating") + .value("PEP_rating_undefined", PEP_rating_undefined) + .value("PEP_rating_cannot_decrypt", PEP_rating_cannot_decrypt) + .value("PEP_rating_have_no_key", PEP_rating_have_no_key) + .value("PEP_rating_unencrypted", PEP_rating_unencrypted) + .value("PEP_rating_unencrypted_for_some", PEP_rating_unencrypted_for_some) + .value("PEP_rating_unreliable", PEP_rating_unreliable) + .value("PEP_rating_reliable", PEP_rating_reliable) + .value("PEP_rating_trusted", PEP_rating_trusted) + .value("PEP_rating_trusted_and_anonymized", PEP_rating_trusted_and_anonymized) + .value("PEP_rating_fully_anonymous", PEP_rating_fully_anonymous) + .value("PEP_rating_mistrust", PEP_rating_mistrust) + .value("PEP_rating_b0rken", PEP_rating_b0rken) + .value("PEP_rating_under_attack", PEP_rating_under_attack); + def("incoming_message", &incoming_message, "msg = incoming_message(mime_text)\n" "\n" diff --git a/test/mp_sync_test.py b/test/mp_sync_test.py index 70f5cd6..1b03d15 100644 --- a/test/mp_sync_test.py +++ b/test/mp_sync_test.py @@ -34,7 +34,7 @@ def pre_existing_peers_with_encrypted_mail(): "SoloA First to GroupA First -- encrypted", "SoloA First to GroupA First -- long encrypted"]]) for action in [ - ("GroupA1", [decrypt_message, [enc_msg]], expect(PEP_rating_reliable)), + ("GroupA1", [decrypt_message, [enc_msg]], expect(pEp.PEP_rating.PEP_rating_reliable)), (flush_all_mails,), ] : yield action @@ -45,7 +45,7 @@ def group_on_keygen(): for action in [ ("GroupA2", [create_account, ["first@group.a", "GroupA First"]]), (cycle_until_no_change, ["GroupA1", "GroupA2"], expect(4)), - ("GroupA2", [decrypt_message, [enc_msg]], expect(PEP_rating_reliable)) + ("GroupA2", [decrypt_message, [enc_msg]], expect(pEp.PEP_rating.PEP_rating_reliable)) ] : yield action return enc_msg @@ -55,9 +55,9 @@ def group_on_cannotdecrypt(): for action in [ ("GroupA2", [create_account, ["first@group.a", "GroupA First"]]), (flush_all_mails,), - ("GroupA2", [decrypt_message, [enc_msg]], expect(PEP_rating_have_no_key)), + ("GroupA2", [decrypt_message, [enc_msg]], expect(pEp.PEP_rating.PEP_rating_have_no_key)), (cycle_until_no_change, ["GroupA1", "GroupA2"], expect(4)), - ("GroupA2", [decrypt_message, [enc_msg]], expect(PEP_rating_reliable)), + ("GroupA2", [decrypt_message, [enc_msg]], expect(pEp.PEP_rating.PEP_rating_reliable)), ] : yield action def group_of_3_members(): @@ -65,7 +65,7 @@ def group_of_3_members(): for action in [ ("GroupA3", [create_account, ["first@group.a", "GroupA First"]]), (cycle_until_no_change, ["GroupA1", "GroupA2", "GroupA3"], expect(4)), - ("GroupA3", [decrypt_message, [enc_msg]], expect(PEP_rating_reliable)) + ("GroupA3", [decrypt_message, [enc_msg]], expect(pEp.PEP_rating.PEP_rating_reliable)) ] : yield action return enc_msg @@ -103,8 +103,8 @@ def keygen_in_a_group_of_3_members(pre_actions=[]): (flush_all_mails, expect(0)), ("GroupA2", [create_account, ["second@group.a", "GroupA Second"]]), (flush_all_mails, expect(0)), - ("GroupA2", [decrypt_message, [enc_msg]], expect(PEP_rating_reliable)), - ("GroupA1", [decrypt_message, [enc_msg]], expect(PEP_rating_reliable)), + ("GroupA2", [decrypt_message, [enc_msg]], expect(pEp.PEP_rating.PEP_rating_reliable)), + ("GroupA1", [decrypt_message, [enc_msg]], expect(pEp.PEP_rating.PEP_rating_reliable)), ] : yield action def group_survives_restart(): @@ -122,11 +122,11 @@ def nokey_in_a_group_of_3_members(): (flush_all_mails,), ("GroupA1", [create_account, ["second@group.a", "GroupA Second"]]), (flush_all_mails,), - ("GroupA1", [decrypt_message, [enc_msg]], expect(PEP_rating_have_no_key)), + ("GroupA1", [decrypt_message, [enc_msg]], expect(pEp.PEP_rating.PEP_rating_have_no_key)), (cycle_until_no_change, ["GroupA1", "GroupA2", "GroupA3"], expect(3)), - ("GroupA1", [decrypt_message, [enc_msg]], expect(PEP_rating_reliable)), + ("GroupA1", [decrypt_message, [enc_msg]], expect(pEp.PEP_rating.PEP_rating_reliable)), ("GroupA2", [create_account, ["second@group.a", "GroupA Second"]]), - ("GroupA2", [decrypt_message, [enc_msg]], expect(PEP_rating_reliable)), + ("GroupA2", [decrypt_message, [enc_msg]], expect(pEp.PEP_rating.PEP_rating_reliable)), ] : yield action if __name__ == "__main__": diff --git a/test/multipEp.py b/test/multipEp.py index 55380bd..d4dbc90 100644 --- a/test/multipEp.py +++ b/test/multipEp.py @@ -9,28 +9,19 @@ import itertools from copy import deepcopy from collections import OrderedDict -# FIXME : move to main pEp module -# PEP_rating : -PEP_rating_undefined = 0 -PEP_rating_cannot_decrypt = 1 -PEP_rating_have_no_key = 2 -PEP_rating_unencrypted = 3 -PEP_rating_unencrypted_for_some = 4 -PEP_rating_unreliable = 5 -PEP_rating_reliable = 6 -PEP_rating_trusted = 7 -PEP_rating_trusted_and_anonymized = 8 -PEP_rating_fully_anonymous = 9 - -PEP_rating_mistrust = -1, -PEP_rating_b0rken = -2, -PEP_rating_under_attack = -3 - # manager globals instances = None # per-instance globals -pEp = None +if(multiprocessing.current_process().name == "MainProcess"): + ctx = multiprocessing.get_context('spawn') + + # import pEp in main process just to get enums + # TODO: would be really great if no session was created until we really use it. + pEp = importlib.import_module("pEp") +else: + pEp = None + handler = None own_addresses = [] indent = 0 @@ -260,8 +251,8 @@ def start_instance(iname, tmpdir=None, instance_addresses = []): tmpdir = tempfile.TemporaryDirectory() tmpdirname = tmpdir.name - conn, child_conn = multiprocessing.Pipe() - proc = multiprocessing.Process( + conn, child_conn = ctx.Pipe() + proc = ctx.Process( target=pEp_instance_main, args=(iname, tmpdirname, instance_addresses, child_conn, msgs_folders, @@ -327,6 +318,8 @@ def run_manager_action(action): return func(*args, **kwargs) def run_scenario(scenario): + global pEp + for a in sys.argv: if a.startswith("only_") and a != "only_" + scenario.__name__ : print("IGNORING: " + scenario.__name__) @@ -335,7 +328,7 @@ def run_scenario(scenario): global handshakes_seen, handshakes_validated, msgs_folders, instances instances = OrderedDict() - with multiprocessing.Manager() as manager: + with ctx.Manager() as manager: msgs_folders = manager.dict() handshakes_seen = manager.list() handshakes_validated = manager.list() @@ -359,7 +352,11 @@ def run_scenario(scenario): output(res, action) action = sc.send(res) - except StopIteration: pass + except StopIteration: + pass + except : + import traceback + traceback.print_exc() if "wait_for_cleanup" in sys.argv: for iname,(proc, conn, tmpdir, execnt) in instances.items():