Browse Source

Includes/namespace/using cleanup

PYADPT-81
heck 5 years ago
parent
commit
50ebe60221
  1. 2
      src/pEp/__init__.py
  2. 262
      src/pEp/native_pEp/basic_api.cc
  3. 36
      src/pEp/native_pEp/basic_api.hh
  4. 446
      src/pEp/native_pEp/identity.cc
  5. 115
      src/pEp/native_pEp/identity.hh
  6. 643
      src/pEp/native_pEp/message.cc
  7. 193
      src/pEp/native_pEp/message.hh
  8. 309
      src/pEp/native_pEp/message_api.cc
  9. 25
      src/pEp/native_pEp/message_api.hh
  10. 349
      src/pEp/native_pEp/pEpmodule.cc
  11. 33
      src/pEp/native_pEp/pEpmodule.hh
  12. 296
      src/pEp/native_pEp/str_attr.cc
  13. 38
      src/pEp/native_pEp/str_attr.hh
  14. 199
      src/pEp/native_pEp/user_interface.cc
  15. 81
      src/pEp/native_pEp/user_interface.hh
  16. 1
      test/pyadpt-81.py

2
src/pEp/__init__.py

@ -17,7 +17,7 @@ import native_pEp
# Executed on module import
def init():
print("init() called")
# native_pEp._init()
native_pEp._init()
# Executed when run as script
def main():

262
src/pEp/native_pEp/basic_api.cc

@ -1,164 +1,172 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
// System
#include <sstream>
// Engine
#include <pEp/keymanagement.h>
#include <pEp/message_api.h>
#include <pEp/Adapter.hh>
// local
#include "basic_api.hh"
namespace pEp {
namespace PythonAdapter {
void update_identity(Identity& ident)
{
if (ident.address() == "")
throw invalid_argument("address needed");
if (ident.user_id() == PEP_OWN_USERID)
throw runtime_error("update_identity: '" PEP_OWN_USERID
"' may only be used for own identities");
PEP_STATUS status = update_identity(pEp::Adapter::session(), ident);
_throw_status(status);
}
void myself(Identity& ident)
{
if (ident.address() == "")
throw invalid_argument("address needed");
if (ident.username() == "")
throw invalid_argument("username needed");
namespace PythonAdapter {
using namespace std;
void update_identity(Identity& ident)
{
if (ident.address() == "")
throw invalid_argument("address needed");
if (ident.user_id() == PEP_OWN_USERID)
throw runtime_error("update_identity: '" PEP_OWN_USERID
"' may only be used for own identities");
PEP_STATUS status = update_identity(pEp::Adapter::session(), ident);
_throw_status(status);
}
if (ident.user_id() == "")
ident.user_id(ident.address());
void myself(Identity& ident)
{
if (ident.address() == "")
throw invalid_argument("address needed");
if (ident.username() == "")
throw invalid_argument("username needed");
PEP_STATUS status = myself(pEp::Adapter::session(), ident);
_throw_status(status);
}
if (ident.user_id() == "")
ident.user_id(ident.address());
string _trustwords(Identity me, Identity partner, string lang, bool full)
{
if (me.fpr() == "" || partner.fpr() == "")
throw invalid_argument("fingerprint needed in Identities");
PEP_STATUS status = myself(pEp::Adapter::session(), ident);
_throw_status(status);
}
if (lang == "" && me.lang() == partner.lang())
lang = me.lang();
string _trustwords(Identity me, Identity partner, string lang, bool full)
{
if (me.fpr() == "" || partner.fpr() == "")
throw invalid_argument("fingerprint needed in Identities");
char *words = NULL;
size_t size = 0;
PEP_STATUS status = get_trustwords(pEp::Adapter::session(), me, partner,
lang.c_str(),&words, &size, full);
_throw_status(status);
return words;
}
if (lang == "" && me.lang() == partner.lang())
lang = me.lang();
void trust_personal_key(Identity ident)
{
if (ident.fpr() == "")
throw invalid_argument("fingerprint needed in Identities");
if (ident.user_id() == "")
throw invalid_argument("user_id must be provided");
char *words = NULL;
size_t size = 0;
PEP_STATUS status = get_trustwords(pEp::Adapter::session(), me, partner,
lang.c_str(),&words, &size, full);
_throw_status(status);
return words;
}
PEP_STATUS status = trust_personal_key(pEp::Adapter::session(), ident);
_throw_status(status);
}
void trust_personal_key(Identity ident)
{
if (ident.fpr() == "")
throw invalid_argument("fingerprint needed in Identities");
if (ident.user_id() == "")
throw invalid_argument("user_id must be provided");
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 = trust_personal_key(pEp::Adapter::session(), ident);
_throw_status(status);
}
PEP_STATUS status = set_identity_flags(pEp::Adapter::session(), ident, flags);
_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");
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 = set_identity_flags(pEp::Adapter::session(), ident, flags);
_throw_status(status);
}
PEP_STATUS status = unset_identity_flags(pEp::Adapter::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");
void key_reset_trust(Identity ident)
{
if (ident.fpr() == "")
throw invalid_argument("fpr needed");
if (ident.address() == "")
throw invalid_argument("address needed");
if (ident.user_id() == "")
throw invalid_argument("user_id needed");
PEP_STATUS status = key_reset_trust(pEp::Adapter::session(), ident);
_throw_status(status);
}
PEP_STATUS status = unset_identity_flags(pEp::Adapter::session(), ident, flags);
_throw_status(status);
}
void key_reset_trust(Identity ident)
{
if (ident.fpr() == "")
throw invalid_argument("fpr needed");
if (ident.address() == "")
throw invalid_argument("address needed");
if (ident.user_id() == "")
throw invalid_argument("user_id needed");
PEP_STATUS status = key_reset_trust(pEp::Adapter::session(), ident);
_throw_status(status);
}
boost::python::list import_key(string key_data)
{
::identity_list *private_keys = NULL;
PEP_STATUS status = ::import_key(pEp::Adapter::session(), key_data.c_str(), key_data.size(), &private_keys);
if (status && status != PEP_KEY_IMPORTED)
_throw_status(status);
auto result = boost::python::list();
for (::identity_list *il = private_keys; il && il->ident; il=il->next) {
::pEp_identity *ident = ::identity_dup(il->ident);
if (!ident) {
free_identity_list(private_keys);
throw bad_alloc();
}
result.append(Identity(ident));
}
boost::python::list import_key(string key_data)
{
::identity_list *private_keys = NULL;
PEP_STATUS status = ::import_key(pEp::Adapter::session(), key_data.c_str(), key_data.size(), &private_keys);
if (status && status != PEP_KEY_IMPORTED)
_throw_status(status);
auto result = boost::python::list();
for (::identity_list *il = private_keys; il && il->ident; il=il->next) {
::pEp_identity *ident = ::identity_dup(il->ident);
if (!ident) {
free_identity_list(private_keys);
return result;
throw bad_alloc();
}
result.append(Identity(ident));
}
string export_key(Identity ident)
{
PEP_STATUS status = PEP_STATUS_OK;
char* key_data = NULL;
size_t size;
status = ::export_key(pEp::Adapter::session(), ident.fpr().c_str(), &key_data, &size);
free_identity_list(private_keys);
return result;
}
_throw_status(status);
return key_data;
}
string export_key(Identity ident)
{
PEP_STATUS status = PEP_STATUS_OK;
char* key_data = NULL;
size_t size;
status = ::export_key(pEp::Adapter::session(), ident.fpr().c_str(), &key_data, &size);
string export_secret_key(Identity ident)
{
PEP_STATUS status = PEP_STATUS_OK;
char* key_data = NULL;
size_t size;
status = ::export_secret_key(pEp::Adapter::session(), ident.fpr().c_str(), &key_data, &size);
_throw_status(status);
return key_data;
}
_throw_status(status);
return key_data;
}
string export_secret_key(Identity ident)
{
PEP_STATUS status = PEP_STATUS_OK;
char* key_data = NULL;
size_t size;
status = ::export_secret_key(pEp::Adapter::session(), ident.fpr().c_str(), &key_data, &size);
void set_own_key(Identity& ident, string fpr)
{
if (ident.address() == "")
throw invalid_argument("address needed");
if (ident.username() == "")
throw invalid_argument("username needed");
if (ident.user_id() == "")
throw invalid_argument("user_id needed");
if (fpr == "")
throw invalid_argument("fpr needed");
const char* fpr_c = fpr.c_str();
PEP_STATUS status = set_own_key(pEp::Adapter::session(), ident, fpr_c);
_throw_status(status);
}
}
_throw_status(status);
return key_data;
}
void set_own_key(Identity& ident, string fpr)
{
if (ident.address() == "")
throw invalid_argument("address needed");
if (ident.username() == "")
throw invalid_argument("username needed");
if (ident.user_id() == "")
throw invalid_argument("user_id needed");
if (fpr == "")
throw invalid_argument("fpr needed");
const char* fpr_c = fpr.c_str();
PEP_STATUS status = set_own_key(pEp::Adapter::session(), ident, fpr_c);
_throw_status(status);
}
} // namespace PythonAdapter
} // namespace pEp {

36
src/pEp/native_pEp/basic_api.hh

@ -6,20 +6,22 @@
#include "pEpmodule.hh"
namespace pEp {
namespace PythonAdapter {
void update_identity(Identity& ident);
void myself(Identity& ident);
string _trustwords(Identity me, Identity partner, string lang, bool full);
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);
void key_reset_trust(Identity ident);
boost::python::list import_key(string key_data);
string export_key(Identity ident);
string export_secret_key(Identity ident);
void set_own_key(Identity& ident, string fpr);
}
}
namespace PythonAdapter {
void update_identity(Identity& ident);
void myself(Identity& ident);
string _trustwords(Identity me, Identity partner, string lang, bool full);
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);
void key_reset_trust(Identity ident);
boost::python::list import_key(string key_data);
string export_key(Identity ident);
string export_secret_key(Identity ident);
void set_own_key(Identity& ident, string fpr);
} // namespace PythonAdapter
} // namespace pEp {

446
src/pEp/native_pEp/identity.cc

@ -1,279 +1,285 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
// System
#include <typeinfo>
#include <sstream>
// Engine
#include <pEp/identity_list.h>
#include <pEp/keymanagement.h>
#include <pEp/key_reset.h>
// local
#include "identity.hh"
#include "pEpmodule.hh"
#include "basic_api.hh"
#include "message_api.hh"
namespace pEp {
namespace PythonAdapter {
Identity::Identity(string address, string username, string user_id,
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);
}
namespace PythonAdapter {
using namespace std;
using namespace boost::python;
Identity::Identity(string address, string username, string user_id,
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);
}
Identity::Identity(const Identity& second)
: _ident(second._ident)
{
Identity::Identity(const Identity& second)
: _ident(second._ident)
{
}
}
Identity::Identity(pEp_identity *ident)
: _ident(ident, &::free_identity)
{
Identity::Identity(pEp_identity *ident)
: _ident(ident, &::free_identity)
{
}
}
Identity::~Identity()
{
Identity::~Identity()
{
}
}
Identity::operator pEp_identity *()
{
return _ident.get();
}
Identity::operator pEp_identity *()
{
return _ident.get();
}
Identity::operator const pEp_identity *() const
{
return _ident.get();
}
Identity::operator const pEp_identity *() const
{
return _ident.get();
}
string Identity::_repr()
{
stringstream build;
build << "Identity(";
string address;
if (_ident->address)
address = string(_ident->address);
build << repr(address) << ", ";
string username;
if (_ident->username)
username = string(_ident->username);
build << repr(username) << ", ";
string user_id;
if (_ident->user_id)
user_id = string(_ident->user_id);
build << repr(user_id) << ", ";
string fpr;
if (_ident->fpr)
fpr = string(_ident->fpr);
build << repr(fpr) << ", ";
build << (int) _ident->comm_type << ", ";
string lang = _ident->lang;
build << repr(lang) << ")";
return build.str();
}
string Identity::_repr()
{
stringstream build;
build << "Identity(";
string address;
if (_ident->address)
address = string(_ident->address);
build << repr(address) << ", ";
string username;
if (_ident->username)
username = string(_ident->username);
build << repr(username) << ", ";
string user_id;
if (_ident->user_id)
user_id = string(_ident->user_id);
build << repr(user_id) << ", ";
string fpr;
if (_ident->fpr)
fpr = string(_ident->fpr);
build << repr(fpr) << ", ";
build << (int) _ident->comm_type << ", ";
string lang = _ident->lang;
build << repr(lang) << ")";
return build.str();
}
string Identity::_str()
{
if (!(_ident->address && _ident->address[0]))
return "";
if (!(_ident->username && _ident->username[0]))
return _ident->address;
return string(_ident->username) + " <" + _ident->address + ">";
}
string Identity::_str()
{
if (!(_ident->address && _ident->address[0]))
return "";
if (!(_ident->username && _ident->username[0]))
return _ident->address;
return string(_ident->username) + " <" + _ident->address + ">";
}
void Identity::username(string value)
{
if (value.length() && value.length() < 5)
throw length_error("username must be at least 5 characters");
void Identity::username(string value)
{
if (value.length() && value.length() < 5)
throw length_error("username must be at least 5 characters");
str_attr(_ident->username, value);
}
str_attr(_ident->username, value);
}
void Identity::lang(string value)
{
if (value == "")
memset(_ident->lang, 0, 3);
else if (value.length() != 2)
throw length_error("length of lang must be 2");
else
memcpy(_ident->lang, value.c_str(), 3);
}
void Identity::lang(string value)
{
if (value == "")
memset(_ident->lang, 0, 3);
else if (value.length() != 2)
throw length_error("length of lang must be 2");
else
memcpy(_ident->lang, value.c_str(), 3);
}
string Identity::lang()
{
return _ident->lang;
}
string Identity::lang()
{
return _ident->lang;
}
int Identity::rating()
{
if (!(_ident->address))
throw invalid_argument("address must be given");
int Identity::rating()
{
if (!(_ident->address))
throw invalid_argument("address must be given");
PEP_rating rating = PEP_rating_undefined;
PEP_STATUS status = ::identity_rating(pEp::Adapter::session(), _ident.get(), &rating);
_throw_status(status);
PEP_rating rating = PEP_rating_undefined;
PEP_STATUS status = ::identity_rating(pEp::Adapter::session(), _ident.get(), &rating);
_throw_status(status);
return (int) rating;
}
return (int) rating;
}
PEP_color Identity::color()
{
return _color(rating());
}
PEP_color Identity::color()
{
return _color(rating());
}
Identity Identity::copy()
{
pEp_identity *dup = ::identity_dup(*this);
if (!dup)
throw bad_alloc();
Identity Identity::copy()
{
pEp_identity *dup = ::identity_dup(*this);
if (!dup)
throw bad_alloc();
return Identity(dup);
}
return Identity(dup);
}
Identity Identity::deepcopy(dict&)
{
return copy();
}
Identity Identity::deepcopy(dict&)
{
return copy();
}
void Identity::update()
{
update_identity(*this);
}
void Identity::update()
{
update_identity(*this);
}
void Identity::key_reset(string fpr)
{
PEP_STATUS status = ::key_reset_identity(pEp::Adapter::session(), *this,
fpr != "" ? fpr.c_str() : nullptr);
_throw_status(status);
}
void Identity::key_reset(string fpr)
{
PEP_STATUS status = ::key_reset_identity(pEp::Adapter::session(), *this,
fpr != "" ? fpr.c_str() : nullptr);
_throw_status(status);
}
void Identity::key_mistrusted()
{
PEP_STATUS status = ::key_mistrusted(pEp::Adapter::session(), *this);
_throw_status(status);
}
void Identity::key_mistrusted()
{
PEP_STATUS status = ::key_mistrusted(pEp::Adapter::session(), *this);
_throw_status(status);
}
bool Identity::is_pEp_user()
{
bool result;
PEP_STATUS status = ::is_pEp_user(pEp::Adapter::session(), *this, &result);
_throw_status(status);
return result;
}
bool Identity::is_pEp_user()
{
bool result;
PEP_STATUS status = ::is_pEp_user(pEp::Adapter::session(), *this, &result);
_throw_status(status);
return result;
}
void Identity::enable_for_sync()
{
PEP_STATUS status = ::enable_identity_for_sync(pEp::Adapter::session(), *this);
_throw_status(status);
}
void Identity::enable_for_sync()
{
PEP_STATUS status = ::enable_identity_for_sync(pEp::Adapter::session(), *this);
_throw_status(status);
}
void Identity::disable_for_sync()
{
PEP_STATUS status = ::disable_identity_for_sync(pEp::Adapter::session(), *this);
_throw_status(status);
}
void Identity::disable_for_sync()
{
PEP_STATUS status = ::disable_identity_for_sync(pEp::Adapter::session(), *this);
_throw_status(status);
}
Myself::Myself(string address, string username, string user_id, string lang)
: Identity(address, username, user_id, "", 0, lang)
Myself::Myself(string address, string username, string user_id, string lang)
: Identity(address, username, user_id, "", 0, lang)
{
if (!(address.length() && username.length()))
throw invalid_argument("address and username must be set");
if (lang.length() && lang.length() != 2)
throw length_error("lang must be an ISO 639-1 language code or empty");
{
if (!(address.length() && username.length()))
throw invalid_argument("address and username must be set");
if (lang.length() && lang.length() != 2)
throw length_error("lang must be an ISO 639-1 language code or empty");
// FIXME: should set .me
// _ident->me = true;
if (user_id.length())
throw runtime_error("user_id feature not yet implemented for Myself");
}
// FIXME: should set .me
// _ident->me = true;
if (user_id.length())
throw runtime_error("user_id feature not yet implemented for Myself");
}
void Myself::update()
{
pEp::PythonAdapter::myself(*this);
}
void Myself::update()
{
pEp::PythonAdapter::myself(*this);
}
Identity identity_attr(pEp_identity *&ident)
{
if (!ident)
throw out_of_range("no identity assigned");
Identity identity_attr(pEp_identity *&ident)
{
if (!ident)
throw out_of_range("no identity assigned");
pEp_identity *_dup = identity_dup(ident);
if (!_dup)
throw bad_alloc();
pEp_identity *_dup = identity_dup(ident);
if (!_dup)
throw bad_alloc();
Identity _ident(_dup);
return _ident;
}
Identity _ident(_dup);
return _ident;
}
void identity_attr(pEp_identity *&ident, object value)
{
Identity& _ident = extract< Identity& >(value);
pEp_identity *_dup = ::identity_dup(_ident);
if (!_dup)
throw bad_alloc();
PEP_STATUS status = update_identity(pEp::Adapter::session(), _dup);
_throw_status(status);
free_identity(ident);
ident = _dup;
}
void identity_attr(pEp_identity *&ident, object value)
{
Identity& _ident = extract< Identity& >(value);
pEp_identity *_dup = ::identity_dup(_ident);
if (!_dup)
throw bad_alloc();
PEP_STATUS status = update_identity(pEp::Adapter::session(), _dup);
_throw_status(status);
free_identity(ident);
ident = _dup;
}
boost::python::list identitylist_attr(identity_list *&il)
{
boost::python::list result;
boost::python::list identitylist_attr(identity_list *&il)
{
boost::python::list result;
for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
pEp_identity *ident = ::identity_dup(_il->ident);
if (!ident)
throw bad_alloc();
result.append(object(Identity(ident)));
}
for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
pEp_identity *ident = ::identity_dup(_il->ident);
if (!ident)
throw bad_alloc();
result.append(object(Identity(ident)));
}
return result;
}
return result;
void identitylist_attr(identity_list *&il, boost::python::list value)
{
identity_list *_il = new_identity_list(NULL);
if (!_il)
throw bad_alloc();
identity_list *_i = _il;
for (int i=0; i<len(value); i++) {
extract< Identity& > extract_identity(value[i]);
if (!extract_identity.check()) {
free_identity_list(_il);
}
void identitylist_attr(identity_list *&il, boost::python::list value)
{
identity_list *_il = new_identity_list(NULL);
if (!_il)
throw bad_alloc();
identity_list *_i = _il;
for (int i=0; i<len(value); i++) {
extract< Identity& > extract_identity(value[i]);
if (!extract_identity.check()) {
free_identity_list(_il);
}
pEp_identity *_ident = extract_identity();
pEp_identity *_dup = ::identity_dup(_ident);
if (!_dup) {
free_identity_list(_il);
throw bad_alloc();
}
PEP_STATUS status = update_identity(pEp::Adapter::session(), _dup);
if (status != PEP_STATUS_OK) {
free_identity_list(_il);
_throw_status(status);
}
_i = identity_list_add(_i, _dup);
if (!_i) {
free_identity_list(_il);
throw bad_alloc();
}
}
free_identity_list(il);
il = _il;
pEp_identity *_ident = extract_identity();
pEp_identity *_dup = ::identity_dup(_ident);
if (!_dup) {
free_identity_list(_il);
throw bad_alloc();
}
PEP_STATUS status = update_identity(pEp::Adapter::session(), _dup);
if (status != PEP_STATUS_OK) {
free_identity_list(_il);
_throw_status(status);
}
_i = identity_list_add(_i, _dup);
if (!_i) {
free_identity_list(_il);
throw bad_alloc();
}
}
free_identity_list(il);
il = _il;
}
} // namespace PythonAdapter
} // namespace pEp {

115
src/pEp/native_pEp/identity.hh

@ -3,91 +3,98 @@
#pragma once
// System
#include <boost/python.hpp>
#include <string>
#include <memory>
#include <cstddef>
// Engine
#include <pEp/pEpEngine.h>
#include <pEp/message_api.h>
//libpEpAdapter
#include "pEp/Adapter.hh"
// local
#include "str_attr.hh"
namespace pEp {
namespace PythonAdapter {
using namespace utility;
using namespace std;
namespace PythonAdapter {
using std::string;
using std::shared_ptr;
// Identity is owning a pEp_identity
// Identity is owning a pEp_identity
class Identity {
protected:
shared_ptr< pEp_identity > _ident;
class Identity {
protected:
shared_ptr< pEp_identity > _ident;
public:
Identity(string address = "", string username = "",
string user_id = "", string fpr = "", int comm_type = 0,
string lang = "", identity_flags_t flags = 0);
public:
Identity(string address = "", string username = "",
string user_id = "", string fpr = "", int comm_type = 0,
string lang = "", identity_flags_t flags = 0);
Identity(const Identity& second);
Identity(pEp_identity *ident);
virtual ~Identity();
operator pEp_identity *();
operator const pEp_identity *() const;
Identity(const Identity& second);
Identity(pEp_identity *ident);
virtual ~Identity();
operator pEp_identity *();
operator const pEp_identity *() const;
string _repr();
string _str();
string _repr();
string _str();
string address() { return str_attr(_ident->address); }
void address(string value) { str_attr(_ident->address, value); }
string address() { return str_attr(_ident->address); }
void address(string value) { str_attr(_ident->address, value); }
string fpr() { return str_attr(_ident->fpr); }
void fpr(string value) { str_attr(_ident->fpr, value); }
string fpr() { return str_attr(_ident->fpr); }
void fpr(string value) { str_attr(_ident->fpr, value); }
string user_id() { return str_attr(_ident->user_id); }
void user_id(string value) { str_attr(_ident->user_id, value); }
string user_id() { return str_attr(_ident->user_id); }
void user_id(string value) { str_attr(_ident->user_id, value); }
string username() { return str_attr(_ident->username); }
void username(string value);
string username() { return str_attr(_ident->username); }
void username(string value);
PEP_comm_type comm_type() { return _ident->comm_type; }
void comm_type(PEP_comm_type value) { _ident->comm_type = value; };
PEP_comm_type comm_type() { return _ident->comm_type; }
void comm_type(PEP_comm_type value) { _ident->comm_type = value; };
std::string lang();
void lang(std::string value);
std::string lang();
void lang(std::string value);
identity_flags_t flags() { return _ident->flags; }
void flags(identity_flags_t flags) { _ident->flags = flags; }
identity_flags_t flags() { return _ident->flags; }
void flags(identity_flags_t flags) { _ident->flags = flags; }
int rating();
PEP_color color();
int rating();
PEP_color color();
Identity copy();
Identity deepcopy(dict& memo);
Identity copy();
Identity deepcopy(dict& memo);
virtual void update();
virtual void update();
void key_reset(string fpr="");
void key_mistrusted();
void key_reset(string fpr="");
void key_mistrusted();
bool is_pEp_user();
bool is_pEp_user();
void enable_for_sync();
void disable_for_sync();
};
void enable_for_sync();
void disable_for_sync();
};
class Myself : public Identity {
public:
Myself(string address, string username, string user_id="", string lang="");
virtual void update();
};
class Myself : public Identity {
public:
Myself(string address, string username, string user_id="", string lang="");
virtual void update();
};
Identity identity_attr(pEp_identity *&ident);
void identity_attr(pEp_identity *&ident, object value);
Identity identity_attr(pEp_identity *&ident);
void identity_attr(pEp_identity *&ident, object value);
boost::python::list identitylist_attr(identity_list *&il);
void identitylist_attr(identity_list *&il, boost::python::list value);
boost::python::list identitylist_attr(identity_list *&il);
void identitylist_attr(identity_list *&il, boost::python::list value);
}
}
} // namespace PythonAdapter
} // namespace pEp {

643
src/pEp/native_pEp/message.cc

@ -1,408 +1,413 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
#include <Python.h>
// System
#include <cstdlib>
#include <cstring>
#include <stdexcept>
#include <sstream>
#include <vector>
#include <Python.h>
// Engine
#include <pEp/mime.h>
#include <pEp/keymanagement.h>
#include <pEp/message_api.h>
// local
#include "message.hh"
#include "message_api.hh"
namespace pEp {
namespace PythonAdapter {
using namespace std;
Message::Blob::Blob(bloblist_t *bl, bool chained) :
_bl(bl), part_of_chain(chained)
{
if (!_bl)
throw bad_alloc();
}
namespace PythonAdapter {
using namespace std;
using namespace boost::python;
Message::Blob::Blob(bloblist_t *bl, bool chained) :
_bl(bl), part_of_chain(chained)
{
if (!_bl)
throw bad_alloc();
}
Message::Blob::Blob(object data, string mime_type, string filename) :
_bl(new_bloblist(NULL, 0, NULL, NULL)), part_of_chain(false)
{
if (!_bl)
throw bad_alloc();
Message::Blob::Blob(object data, string mime_type, string filename) :
_bl(new_bloblist(NULL, 0, NULL, NULL)), part_of_chain(false)
{
if (!_bl)
throw bad_alloc();
Py_buffer src;
int result = PyObject_GetBuffer(data.ptr(), &src, PyBUF_CONTIG_RO);
if (result)
throw invalid_argument("need a contiguous buffer to read");
char *mem = (char *)malloc(src.len);
if (!mem) {
PyBuffer_Release(&src);
throw bad_alloc();
}
Py_buffer src;
int result = PyObject_GetBuffer(data.ptr(), &src, PyBUF_CONTIG_RO);
if (result)
throw invalid_argument("need a contiguous buffer to read");
memcpy(mem, src.buf, src.len);
free(_bl->value);
_bl->size = src.len;
_bl->value = mem;
char *mem = (char *)malloc(src.len);
if (!mem) {
PyBuffer_Release(&src);
throw bad_alloc();
}
PyBuffer_Release(&src);
memcpy(mem, src.buf, src.len);
free(_bl->value);
_bl->size = src.len;
_bl->value = mem;
this->mime_type(mime_type);
this->filename(filename);
}
PyBuffer_Release(&src);
Message::Blob::Blob(const Message::Blob& second) :
_bl(second._bl), part_of_chain(true)
{
this->mime_type(mime_type);
this->filename(filename);
}
}
Message::Blob::Blob(const Message::Blob& second) :
_bl(second._bl), part_of_chain(true)
{
Message::Blob::~Blob()
{
if (!part_of_chain) {
free(_bl->value);
free(_bl);
}
}
}
string Message::Blob::_repr()
{
stringstream build;
build << "Blob(";
if (!_bl) {
build << "b'', '', ''";
}
else {
build << "bytes(" << _bl->size << "), ";
string mime_type;
if (_bl->mime_type)
mime_type = string(_bl->mime_type);
string filename;
if (_bl->filename)
filename = string(_bl->filename);
build << repr(mime_type) << ", ";
build << repr(filename);
}
build << ")";
return build.str();
}
Message::Blob::~Blob()
{
if (!part_of_chain) {
free(_bl->value);
free(_bl);
}
}
int Message::Blob::getbuffer(PyObject *self, Py_buffer *view, int flags) {
bloblist_t *bl = NULL;
string Message::Blob::_repr()
{
stringstream build;
build << "Blob(";
if (!_bl) {
build << "b'', '', ''";
}
else {
build << "bytes(" << _bl->size << "), ";
string mime_type;
if (_bl->mime_type)
mime_type = string(_bl->mime_type);
string filename;
if (_bl->filename)
filename = string(_bl->filename);
build << repr(mime_type) << ", ";
build << repr(filename);
}
build << ")";
return build.str();
}
try {
Message::Blob& blob = extract< Message::Blob& >(self);
bl = blob._bl;
}
catch (exception& e) {
PyErr_SetString(PyExc_RuntimeError, "extract not possible");
view->obj = NULL;
return -1;
}
int Message::Blob::getbuffer(PyObject *self, Py_buffer *view, int flags) {
bloblist_t *bl = NULL;
if (!(bl && bl->value)) {
PyErr_SetString(PyExc_RuntimeError, "no data available");
view->obj = NULL;
return -1;
}
try {
Message::Blob& blob = extract< Message::Blob& >(self);
bl = blob._bl;
}
catch (exception& e) {
PyErr_SetString(PyExc_RuntimeError, "extract not possible");
view->obj = NULL;
return -1;
}
return PyBuffer_FillInfo(view, self, bl->value, bl->size, 0, flags);
}
if (!(bl && bl->value)) {
PyErr_SetString(PyExc_RuntimeError, "no data available");
view->obj = NULL;
return -1;
}
string Message::Blob::decode(string encoding)
{
if (encoding == "") {
string _mime_type = _bl->mime_type ? _bl->mime_type : "";
encoding = "ascii";
return PyBuffer_FillInfo(view, self, bl->value, bl->size, 0, flags);
}
if (_mime_type == "application/pEp.sync")
encoding = "pep.sync";
string Message::Blob::decode(string encoding)
{
if (encoding == "") {
string _mime_type = _bl->mime_type ? _bl->mime_type : "";
encoding = "ascii";
if (_mime_type == "application/pEp.keyreset")
encoding = "pep.distribution";
if (_mime_type == "application/pEp.sync")
encoding = "pep.sync";
}
object codecs = import("codecs");
object _decode = codecs.attr("decode");
return call< string >(_decode.ptr(), this, encoding);
}
if (_mime_type == "application/pEp.keyreset")
encoding = "pep.distribution";
PyBufferProcs Message::Blob::bp = { getbuffer, NULL };
}
object codecs = import("codecs");
object _decode = codecs.attr("decode");
return call< string >(_decode.ptr(), this, encoding);
}
Message::Message(int dir, Identity *from)
: _msg(new_message((PEP_msg_direction) dir), &free_message)
{
if (!_msg)
throw bad_alloc();
PyBufferProcs Message::Blob::bp = { getbuffer, NULL };
if (from) {
_msg->from = ::identity_dup(*from);
if (!_msg->from)
throw bad_alloc();
_msg->dir = (PEP_msg_direction) dir;
}
}
Message::Message(int dir, Identity *from)
: _msg(new_message((PEP_msg_direction) dir), &free_message)
{
if (!_msg)
Message::Message(string mimetext)
: _msg(NULL, &free_message)
{
message *_cpy;
PEP_STATUS status = mime_decode_message(mimetext.c_str(),
mimetext.size(), &_cpy, NULL);
switch (status) {
case PEP_STATUS_OK:
if (_cpy)
_cpy->dir = PEP_dir_outgoing;
else
_cpy = new_message(PEP_dir_outgoing);
if (!_cpy)
throw bad_alloc();
if (from) {
_msg->from = ::identity_dup(*from);
if (!_msg->from)
throw bad_alloc();
_msg->dir = (PEP_msg_direction) dir;
}
}
_msg = shared_ptr< message >(_cpy);
break;
Message::Message(string mimetext)
: _msg(NULL, &free_message)
{
message *_cpy;
PEP_STATUS status = mime_decode_message(mimetext.c_str(),
mimetext.size(), &_cpy, NULL);
switch (status) {
case PEP_STATUS_OK:
if (_cpy)
_cpy->dir = PEP_dir_outgoing;
else
_cpy = new_message(PEP_dir_outgoing);
if (!_cpy)
throw bad_alloc();
_msg = shared_ptr< message >(_cpy);
break;
case PEP_BUFFER_TOO_SMALL:
throw runtime_error("mime_decode_message: buffer too small");
case PEP_CANNOT_CREATE_TEMP_FILE:
throw runtime_error("mime_decode_message: cannot create temp file");
case PEP_OUT_OF_MEMORY:
throw bad_alloc();
default:
stringstream build;
build << "mime_decode_message: unknown error (" << (int) status << ")";
throw runtime_error(build.str());
}
}
case PEP_BUFFER_TOO_SMALL:
throw runtime_error("mime_decode_message: buffer too small");
Message::Message(const Message& second)
: _msg(second._msg)
{
if (!_msg.get())
throw bad_alloc();
}
case PEP_CANNOT_CREATE_TEMP_FILE:
throw runtime_error("mime_decode_message: cannot create temp file");
Message::Message(message *msg)
: _msg(::message_dup(msg), &free_message)
{
case PEP_OUT_OF_MEMORY:
throw bad_alloc();
}
default:
stringstream build;
build << "mime_decode_message: unknown error (" << (int) status << ")";
throw runtime_error(build.str());
}
}
Message::~Message()
{
Message::Message(const Message& second)
: _msg(second._msg)
{
if (!_msg.get())
throw bad_alloc();
}
}
Message::Message(message *msg)
: _msg(::message_dup(msg), &free_message)
{
Message::operator message *()
{
return _msg.get();
}
}
Message::operator const message *() const
{
return _msg.get();
}
Message::~Message()
{
string Message::_str()
{
if (!(_msg->from && _msg->from->address && _msg->from->address[0]))
throw out_of_range(".from_.address missing");
}
char *mimetext;
string result;
Message::operator message *()
{
return _msg.get();
}
PEP_STATUS status = mime_encode_message(*this, false, &mimetext, false);
switch (status) {
case PEP_STATUS_OK:
result = mimetext;
free(mimetext);
break;
Message::operator const message *() const
{
return _msg.get();
}
case PEP_BUFFER_TOO_SMALL:
throw runtime_error("mime_encode_message: buffer too small");
string Message::_str()
{
if (!(_msg->from && _msg->from->address && _msg->from->address[0]))
throw out_of_range(".from_.address missing");
case PEP_CANNOT_CREATE_TEMP_FILE:
throw runtime_error("mime_encode_message: cannot create temp file");
char *mimetext;
string result;
case PEP_OUT_OF_MEMORY:
throw bad_alloc();
PEP_STATUS status = mime_encode_message(*this, false, &mimetext, false);
switch (status) {
case PEP_STATUS_OK:
result = mimetext;
free(mimetext);
break;
default:
stringstream build;
build << "mime_encode_message: unknown error (" << (int) status << ")";
throw runtime_error(build.str());
}
case PEP_BUFFER_TOO_SMALL:
throw runtime_error("mime_encode_message: buffer too small");
return result;
}
case PEP_CANNOT_CREATE_TEMP_FILE:
throw runtime_error("mime_encode_message: cannot create temp file");
string Message::_repr()
{
case PEP_OUT_OF_MEMORY:
throw bad_alloc();
default:
stringstream build;
build << "Message(" << repr(_str()) << ")";
return build.str();
}
build << "mime_encode_message: unknown error (" << (int) status << ")";
throw runtime_error(build.str());
}
boost::python::tuple Message::attachments()
{
boost::python::list l;
return result;
}
for (bloblist_t *bl = _msg->attachments; bl && bl->value; bl =
bl->next) {
l.append(Blob(bl, true));
}
string Message::_repr()
{
stringstream build;
build << "Message(" << repr(_str()) << ")";
return build.str();
}
return boost::python::tuple(l);
}
boost::python::tuple Message::attachments()
{
boost::python::list l;
void Message::attachments(boost::python::list value)
{
bloblist_t *bl = new_bloblist(NULL, 0, NULL, NULL);
if (!bl)
throw bad_alloc();
for (bloblist_t *bl = _msg->attachments; bl && bl->value; bl =
bl->next) {
l.append(Blob(bl, true));
}
bloblist_t *_l = bl;
for (int i=0; i<len(value); i++) {
Message::Blob& blob = extract< Message::Blob& >(value[i]);
_l = bloblist_add(_l, blob._bl->value, blob._bl->size,
blob._bl->mime_type, blob._bl->filename);
if (!_l) {
for (_l = bl; _l && _l->value; ) {
free(_l->mime_type);
free(_l->filename);
bloblist_t *_ll = _l;
_l = _l->next;
free(_ll);
}
throw bad_alloc();
}
}
return boost::python::tuple(l);
}
for (int i=0; i<len(value); i++) {
Message::Blob& blob = extract< Message::Blob& >(value[i]);
blob._bl->value = NULL;
blob._bl->size = 0;
free(blob._bl->mime_type);
blob._bl->mime_type = NULL;
free(blob._bl->filename);
blob._bl->filename = NULL;
void Message::attachments(boost::python::list value)
{
bloblist_t *bl = new_bloblist(NULL, 0, NULL, NULL);
if (!bl)
throw bad_alloc();
bloblist_t *_l = bl;
for (int i=0; i<len(value); i++) {
Message::Blob& blob = extract< Message::Blob& >(value[i]);
_l = bloblist_add(_l, blob._bl->value, blob._bl->size,
blob._bl->mime_type, blob._bl->filename);
if (!_l) {
for (_l = bl; _l && _l->value; ) {
free(_l->mime_type);
free(_l->filename);
bloblist_t *_ll = _l;
_l = _l->next;
free(_ll);
}
free_bloblist(_msg->attachments);
_msg->attachments = bl;
throw bad_alloc();
}
}
Message Message::encrypt()
{
boost::python::list extra;
return encrypt_message(*this, extra, PEP_enc_PGP_MIME, 0);
}
for (int i=0; i<len(value); i++) {
Message::Blob& blob = extract< Message::Blob& >(value[i]);
blob._bl->value = NULL;
blob._bl->size = 0;
free(blob._bl->mime_type);
blob._bl->mime_type = NULL;
free(blob._bl->filename);
blob._bl->filename = NULL;
}
Message Message::_encrypt(boost::python::list extra, int enc_format, int flags)
{
if (!enc_format)
enc_format = PEP_enc_PGP_MIME;
return encrypt_message(*this, extra, enc_format, flags);
}
free_bloblist(_msg->attachments);
_msg->attachments = bl;
}
boost::python::tuple Message::decrypt(int flags) {
return pEp::PythonAdapter::decrypt_message(*this, flags);
}
Message Message::encrypt()
{
boost::python::list extra;
return encrypt_message(*this, extra, PEP_enc_PGP_MIME, 0);
}
PEP_rating Message::outgoing_rating()
{
if (_msg->dir != PEP_dir_outgoing)
throw invalid_argument("Message.dir must be outgoing");
Message Message::_encrypt(boost::python::list extra, int enc_format, int flags)
{
if (!enc_format)
enc_format = PEP_enc_PGP_MIME;
return encrypt_message(*this, extra, enc_format, flags);
}
if (from().address() == "")
throw invalid_argument("from.address needed");
if (from().username() == "")
throw invalid_argument("from.username needed");
boost::python::tuple Message::decrypt(int flags) {
return pEp::PythonAdapter::decrypt_message(*this, flags);
}
if (len(to()) + len(cc()) == 0)
throw invalid_argument("either to or cc needed");
PEP_rating Message::outgoing_rating()
{
if (_msg->dir != PEP_dir_outgoing)
throw invalid_argument("Message.dir must be outgoing");
PEP_STATUS status = myself(pEp::Adapter::session(), _msg->from);
_throw_status(status);
if (from().address() == "")
throw invalid_argument("from.address needed");
if (from().username() == "")
throw invalid_argument("from.username needed");
PEP_rating rating = PEP_rating_undefined;
status = outgoing_message_rating(pEp::Adapter::session(), *this, &rating);
_throw_status(status);
if (len(to()) + len(cc()) == 0)
throw invalid_argument("either to or cc needed");
return rating;
}
PEP_STATUS status = myself(pEp::Adapter::session(), _msg->from);
_throw_status(status);
PEP_color Message::outgoing_color()
{
return _color(outgoing_rating());
}
PEP_rating rating = PEP_rating_undefined;
status = outgoing_message_rating(pEp::Adapter::session(), *this, &rating);
_throw_status(status);
Message Message::copy()
{
message *dup = message_dup(*this);
if (!dup)
throw bad_alloc();
return Message(dup);
}
return rating;
}
Message Message::deepcopy(dict&)
{
return copy();
}
PEP_color Message::outgoing_color()
{
return _color(outgoing_rating());
}
Message outgoing_message(Identity me)
{
if (me.address().empty() || me.user_id().empty())
throw runtime_error("at least address and user_id of own user needed");
Message Message::copy()
{
message *dup = message_dup(*this);
if (!dup)
throw bad_alloc();
return Message(dup);
}
::myself(pEp::Adapter::session(), me);
auto m = Message(PEP_dir_outgoing, &me);
return m;
}
Message Message::deepcopy(dict&)
{
return copy();
}
static object update(Identity ident)
{
if (ident.address().empty())
throw runtime_error("at least address needed");
update_identity(pEp::Adapter::session(), ident);
return object(ident);
}
Message outgoing_message(Identity me)
{
if (me.address().empty() || me.user_id().empty())
throw runtime_error("at least address and user_id of own user needed");
static boost::python::list update(boost::python::list il)
{
for (int i=0; i<len(il); i++) {
update(extract< Identity >(il[i]));
}
::myself(pEp::Adapter::session(), me);
auto m = Message(PEP_dir_outgoing, &me);
return m;
}
return il;
}
static object update(Identity ident)
{
if (ident.address().empty())
throw runtime_error("at least address needed");
update_identity(pEp::Adapter::session(), ident);
return object(ident);
}
Message incoming_message(string mime_text)
{
auto m = Message(mime_text);
m.dir(PEP_dir_incoming);
static boost::python::list update(boost::python::list il)
{
for (int i=0; i<len(il); i++) {
update(extract< Identity >(il[i]));
}
try {
m.from(update(m.from()));
}
catch (out_of_range&) { }
return il;
}
try {
m.recv_by(update(m.recv_by()));
}
catch (out_of_range&) { }
Message incoming_message(string mime_text)
{
auto m = Message(mime_text);
m.dir(PEP_dir_incoming);
m.to(update(m.to()));
m.cc(update(m.cc()));
m.reply_to(update(m.reply_to()));
try {
m.from(update(m.from()));
}
catch (out_of_range&) { }
return m;
}
try {
m.recv_by(update(m.recv_by()));
}
catch (out_of_range&) { }
m.to(update(m.to()));
m.cc(update(m.cc()));
m.reply_to(update(m.reply_to()));
return m;
}
} // namespace PythonAdapter
} // namespace pEp {

193
src/pEp/native_pEp/message.hh

@ -3,145 +3,150 @@
#pragma once
// System
#include <string>
#include <boost/python.hpp>
#include <boost/lexical_cast.hpp>
#include <string>
// Engine
#include <pEp/message.h>
#include <pEp/message_api.h>
// local
#include "str_attr.hh"
#include "identity.hh"
namespace pEp {
namespace PythonAdapter {
using namespace std;
using namespace boost::python;
using boost::lexical_cast;
namespace PythonAdapter {
using std::string;
using std::runtime_error;
using std::invalid_argument;
using boost::lexical_cast;
// Message is owning a message struct
// Message is owning a message struct
class Message {
shared_ptr< ::message > _msg;
class Message {
shared_ptr< ::message > _msg;
public:
// Blob is owning a bloblist_t struct - or not and just managing
// one depending on part_of_chain
public:
// Blob is owning a bloblist_t struct - or not and just managing
// one depending on part_of_chain
class Blob {
bloblist_t *_bl;
bool part_of_chain;
class Blob {
bloblist_t *_bl;
bool part_of_chain;
public:
Blob(bloblist_t *bl = new_bloblist(NULL, 0, NULL, NULL),
bool chained = false);
Blob(object data, string mime_type = "", string filename = "");
Blob(const Blob& second);
~Blob();
public:
Blob(bloblist_t *bl = new_bloblist(NULL, 0, NULL, NULL),
bool chained = false);
Blob(object data, string mime_type = "", string filename = "");
Blob(const Blob& second);
~Blob();
string _repr();
string _repr();
string mime_type() { return _bl ? str_attr(_bl->mime_type) : ""; }
void mime_type(string value) { str_attr(_bl->mime_type, value); }
string mime_type() { return _bl ? str_attr(_bl->mime_type) : ""; }
void mime_type(string value) { str_attr(_bl->mime_type, value); }
string filename() { return str_attr(_bl->filename); }
void filename(string value) { str_attr(_bl->filename, value); }
string filename() { return str_attr(_bl->filename); }
void filename(string value) { str_attr(_bl->filename, value); }
size_t size() { return _bl->size; }
string decode(string encoding);
string decode() { return decode(""); }
size_t size() { return _bl->size; }
string decode(string encoding);
string decode() { return decode(""); }
static PyBufferProcs bp;
static PyBufferProcs bp;
friend class Message;
friend class Message;
protected:
static int getbuffer(PyObject *self, Py_buffer *view, int flags);
};
protected:
static int getbuffer(PyObject *self, Py_buffer *view, int flags);
};
Message(int dir = PEP_dir_outgoing, Identity *from = NULL);
Message(string mimetext);
Message(const Message& second);
Message(message *msg);
~Message();
operator message *();
operator const message *() const;
Message(int dir = PEP_dir_outgoing, Identity *from = NULL);
Message(string mimetext);
Message(const Message& second);
Message(message *msg);
~Message();
operator message *();
operator const message *() const;
string _str();
string _repr();
string _str();
string _repr();
PEP_msg_direction dir() { return _msg->dir; }
void dir(PEP_msg_direction value) { _msg->dir = value; }
PEP_msg_direction dir() { return _msg->dir; }
void dir(PEP_msg_direction value) { _msg->dir = value; }
string id() { return str_attr(_msg->id); }
void id(string value) { str_attr(_msg->id, value); }
string id() { return str_attr(_msg->id); }
void id(string value) { str_attr(_msg->id, value); }
string shortmsg() { return str_attr(_msg->shortmsg); }
void shortmsg(string value) { str_attr(_msg->shortmsg, value); }
string shortmsg() { return str_attr(_msg->shortmsg); }
void shortmsg(string value) { str_attr(_msg->shortmsg, value); }
string longmsg() { return str_attr(_msg->longmsg); }
void longmsg(string value) { str_attr(_msg->longmsg, value); }
string longmsg() { return str_attr(_msg->longmsg); }
void longmsg(string value) { str_attr(_msg->longmsg, value); }
string longmsg_formatted() { return str_attr(_msg->longmsg_formatted); }
void longmsg_formatted(string value) { str_attr(_msg->longmsg_formatted, value); }
string longmsg_formatted() { return str_attr(_msg->longmsg_formatted); }
void longmsg_formatted(string value) { str_attr(_msg->longmsg_formatted, value); }
boost::python::tuple attachments();
void attachments(boost::python::list value);
boost::python::tuple attachments();
void attachments(boost::python::list value);
time_t sent() { return timestamp_attr(_msg->sent); }
void sent(time_t value) { timestamp_attr(_msg->sent, value); }
time_t sent() { return timestamp_attr(_msg->sent); }
void sent(time_t value) { timestamp_attr(_msg->sent, value); }
time_t recv() { return timestamp_attr(_msg->recv); }
void recv(time_t value) { timestamp_attr(_msg->recv, value); }
time_t recv() { return timestamp_attr(_msg->recv); }
void recv(time_t value) { timestamp_attr(_msg->recv, value); }
Identity from() { return identity_attr(_msg->from); }
void from(object value) { identity_attr(_msg->from, value); }
Identity from() { return identity_attr(_msg->from); }
void from(object value) { identity_attr(_msg->from, value); }
boost::python::list to() { return identitylist_attr(_msg->to); }
void to(boost::python::list value) { identitylist_attr(_msg->to, value); }
boost::python::list to() { return identitylist_attr(_msg->to); }
void to(boost::python::list value) { identitylist_attr(_msg->to, value); }
Identity recv_by() { return identity_attr(_msg->recv_by); }
void recv_by(object value) { identity_attr(_msg->recv_by, value); }
Identity recv_by() { return identity_attr(_msg->recv_by); }
void recv_by(object value) { identity_attr(_msg->recv_by, value); }
boost::python::list cc() { return identitylist_attr(_msg->cc); }
void cc(boost::python::list value) { identitylist_attr(_msg->cc, value); }
boost::python::list cc() { return identitylist_attr(_msg->cc); }
void cc(boost::python::list value) { identitylist_attr(_msg->cc, value); }
boost::python::list bcc() { return identitylist_attr(_msg->bcc); }
void bcc(boost::python::list value) { identitylist_attr(_msg->bcc, value); }
boost::python::list bcc() { return identitylist_attr(_msg->bcc); }
void bcc(boost::python::list value) { identitylist_attr(_msg->bcc, value); }
boost::python::list reply_to() { return identitylist_attr(_msg->reply_to); }
void reply_to(boost::python::list value) { identitylist_attr(_msg->reply_to, value); }
boost::python::list reply_to() { return identitylist_attr(_msg->reply_to); }
void reply_to(boost::python::list value) { identitylist_attr(_msg->reply_to, value); }
boost::python::list in_reply_to() { return strlist_attr(_msg->in_reply_to); }
void in_reply_to(boost::python::list value) { strlist_attr(_msg->in_reply_to, value); }
boost::python::list in_reply_to() { return strlist_attr(_msg->in_reply_to); }
void in_reply_to(boost::python::list value) { strlist_attr(_msg->in_reply_to, value); }
boost::python::list references() { return strlist_attr(_msg->references); }
void references(boost::python::list value) { strlist_attr(_msg->references, value); }
boost::python::list references() { return strlist_attr(_msg->references); }
void references(boost::python::list value) { strlist_attr(_msg->references, value); }
boost::python::list keywords() { return strlist_attr(_msg->keywords); }
void keywords(boost::python::list value) { strlist_attr(_msg->keywords, value); }
boost::python::list keywords() { return strlist_attr(_msg->keywords); }
void keywords(boost::python::list value) { strlist_attr(_msg->keywords, value); }
string comments() { return str_attr(_msg->comments); }
void comments(string value) { str_attr(_msg->comments, value); }
string comments() { return str_attr(_msg->comments); }
void comments(string value) { str_attr(_msg->comments, value); }
dict opt_fields() { return strdict_attr(_msg->opt_fields); }
void opt_fields(dict value) { return strdict_attr(_msg->opt_fields, value); }
dict opt_fields() { return strdict_attr(_msg->opt_fields); }
void opt_fields(dict value) { return strdict_attr(_msg->opt_fields, value); }
PEP_enc_format enc_format() { return _msg->enc_format; }
void enc_format(PEP_enc_format value) { _msg->enc_format = value; }
PEP_enc_format enc_format() { return _msg->enc_format; }
void enc_format(PEP_enc_format value) { _msg->enc_format = value; }
Message encrypt();
Message _encrypt(boost::python::list extra, int enc_format=4, int flags=0);
Message encrypt();
Message _encrypt(boost::python::list extra, int enc_format=4, int flags=0);
boost::python::tuple decrypt(int flags=0);
PEP_rating outgoing_rating();
PEP_color outgoing_color();
Message deepcopy(dict& memo);
Message copy();
};
boost::python::tuple decrypt(int flags=0);
PEP_rating outgoing_rating();
PEP_color outgoing_color();
Message deepcopy(dict& memo);
Message copy();
};
Message outgoing_message(Identity me);
Message incoming_message(string mime_text);
Message outgoing_message(Identity me);
Message incoming_message(string mime_text);
}
}
} // namespace PythonAdapter
} // namespace pEp {

309
src/pEp/native_pEp/message_api.cc

@ -1,168 +1,173 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
// Engine
#include <pEp/pEpEngine.h>
#include <pEp/message_api.h>
#include <pEp/sync_api.h>
#include <pEp/sync_codec.h>
#include <pEp/distribution_codec.h>
// local
#include "message_api.hh"
#include "basic_api.hh"
namespace pEp {
namespace PythonAdapter {
Message encrypt_message(Message src, boost::python::list extra, int enc_format,
int flags)
{
Identity _from = src.from();
if (_from.address() == "")
throw invalid_argument("encrypt_message: src.from_.address empty");
if (_from.username() == "")
throw invalid_argument("encrypt_message: src.from_.username empty");
if (_from.user_id() == "")
src.from().user_id(_from.address());
stringlist_t *_extra = to_stringlist(extra);
PEP_enc_format _enc_format = (PEP_enc_format) enc_format;
PEP_encrypt_flags_t _flags = (PEP_encrypt_flags_t) flags;
message *_dst = NULL;
message *_src = src;
PEP_STATUS status = encrypt_message(pEp::Adapter::session(), _src, _extra, &_dst,
_enc_format, _flags);
free_stringlist(_extra);
_throw_status(status);
if (!_dst || _dst == _src)
return Message(_src);
return Message(_dst);
}
boost::python::tuple decrypt_message(Message src, int flags)
{
message *_dst = NULL;
stringlist_t *_keylist = NULL;
PEP_rating _rating = PEP_rating_undefined;
PEP_decrypt_flags_t _flags = (PEP_decrypt_flags_t) flags;
message *_src = src;
PEP_STATUS status = ::decrypt_message(pEp::Adapter::session(), _src, &_dst, &_keylist,
&_rating, &_flags);
_throw_status(status);
boost::python::list keylist;
if (_keylist) {
keylist = from_stringlist(_keylist);
free_stringlist(_keylist);
}
Message dst = _dst ? Message(_dst) : Message(src);
return boost::python::make_tuple(dst, keylist, _rating, _flags);
}
PEP_color _color(int rating)
{
return ::color_from_rating((PEP_rating) rating);
}
boost::python::tuple sync_decode(object buffer)
{
Py_buffer src;
int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO);
if (result)
throw invalid_argument("need a contiguous buffer to read");
char *dst = NULL;
PEP_STATUS status = PER_to_XER_Sync_msg((char *) src.buf, src.len, &dst);
PyBuffer_Release(&src);
_throw_status(status);
string _dst(dst);
free(dst);
return boost::python::make_tuple(_dst, 0);
}
static boost::python::tuple sync_encode(string text)
{
char *data = NULL;
size_t size = 0;
PEP_STATUS status = XER_to_PER_Sync_msg(text.c_str(), &data, &size);
_throw_status(status);
PyObject *ba = PyBytes_FromStringAndSize(data, size);
free(data);
if (!ba)
throw bad_alloc();
return boost::python::make_tuple(object(handle<>(ba)), 0);
}
boost::python::tuple Distribution_decode(object buffer)
{
Py_buffer src;
int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO);
if (result)
throw invalid_argument("need a contiguous buffer to read");
char *dst = NULL;
PEP_STATUS status = PER_to_XER_Distribution_msg((char *) src.buf, src.len, &dst);
PyBuffer_Release(&src);
_throw_status(status);
string _dst(dst);
free(dst);
return boost::python::make_tuple(_dst, 0);
}
static boost::python::tuple Distribution_encode(string text)
{
char *data = NULL;
size_t size = 0;
PEP_STATUS status = XER_to_PER_Distribution_msg(text.c_str(), &data, &size);
_throw_status(status);
PyObject *ba = PyBytes_FromStringAndSize(data, size);
free(data);
if (!ba)
throw bad_alloc();
return boost::python::make_tuple(object(handle<>(ba)), 0);
}
object sync_search(string name)
{
if (name != "pep.sync") {
return object();
}
else {
object codecs = import("codecs");
object CodecInfo = codecs.attr("CodecInfo");
object _sync_decode = make_function(sync_decode);
object _sync_encode = make_function(sync_encode);
return call< object >(CodecInfo.ptr(), _sync_encode, _sync_decode);
}
}
object distribution_search(string name)
{
if (name != "pep.distribution") {
return object();
}
else {
object codecs = import("codecs");
object CodecInfo = codecs.attr("CodecInfo");
object _distribution_decode = make_function(Distribution_decode);
object _distribution_encode = make_function(Distribution_encode);
return call< object >(CodecInfo.ptr(), _distribution_encode, _distribution_decode);
}
}
namespace PythonAdapter {
using namespace std;
using namespace boost::python;
Message encrypt_message(Message src, boost::python::list extra, int enc_format, int flags)
{
Identity _from = src.from();
if (_from.address() == "")
throw invalid_argument("encrypt_message: src.from_.address empty");
if (_from.username() == "")
throw invalid_argument("encrypt_message: src.from_.username empty");
if (_from.user_id() == "")
src.from().user_id(_from.address());
stringlist_t *_extra = to_stringlist(extra);
PEP_enc_format _enc_format = (PEP_enc_format) enc_format;
PEP_encrypt_flags_t _flags = (PEP_encrypt_flags_t) flags;
message *_dst = NULL;
message *_src = src;
PEP_STATUS status = encrypt_message(pEp::Adapter::session(), _src, _extra, &_dst,
_enc_format, _flags);
free_stringlist(_extra);
_throw_status(status);
if (!_dst || _dst == _src)
return Message(_src);
return Message(_dst);
}
boost::python::tuple decrypt_message(Message src, int flags)
{
message *_dst = NULL;
stringlist_t *_keylist = NULL;
PEP_rating _rating = PEP_rating_undefined;
PEP_decrypt_flags_t _flags = (PEP_decrypt_flags_t) flags;
message *_src = src;
PEP_STATUS status = ::decrypt_message(pEp::Adapter::session(), _src, &_dst, &_keylist,
&_rating, &_flags);
_throw_status(status);
boost::python::list keylist;
if (_keylist) {
keylist = from_stringlist(_keylist);
free_stringlist(_keylist);
}
Message dst = _dst ? Message(_dst) : Message(src);
return boost::python::make_tuple(dst, keylist, _rating, _flags);
}
PEP_color _color(int rating)
{
return ::color_from_rating((PEP_rating) rating);
}
boost::python::tuple sync_decode(object buffer)
{
Py_buffer src;
int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO);
if (result)
throw invalid_argument("need a contiguous buffer to read");
char *dst = NULL;
PEP_STATUS status = PER_to_XER_Sync_msg((char *) src.buf, src.len, &dst);
PyBuffer_Release(&src);
_throw_status(status);
string _dst(dst);
free(dst);
return boost::python::make_tuple(_dst, 0);
}
static boost::python::tuple sync_encode(string text)
{
char *data = NULL;
size_t size = 0;
PEP_STATUS status = XER_to_PER_Sync_msg(text.c_str(), &data, &size);
_throw_status(status);
PyObject *ba = PyBytes_FromStringAndSize(data, size);
free(data);
if (!ba)
throw bad_alloc();
return boost::python::make_tuple(object(handle<>(ba)), 0);
}
boost::python::tuple Distribution_decode(object buffer)
{
Py_buffer src;
int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO);
if (result)
throw invalid_argument("need a contiguous buffer to read");
char *dst = NULL;
PEP_STATUS status = PER_to_XER_Distribution_msg((char *) src.buf, src.len, &dst);
PyBuffer_Release(&src);
_throw_status(status);
string _dst(dst);
free(dst);
return boost::python::make_tuple(_dst, 0);
}
static boost::python::tuple Distribution_encode(string text)
{
char *data = NULL;
size_t size = 0;
PEP_STATUS status = XER_to_PER_Distribution_msg(text.c_str(), &data, &size);
_throw_status(status);
PyObject *ba = PyBytes_FromStringAndSize(data, size);
free(data);
if (!ba)
throw bad_alloc();
return boost::python::make_tuple(object(handle<>(ba)), 0);
}
object sync_search(string name)
{
if (name != "pep.sync") {
return object();
}
else {
object codecs = import("codecs");
object CodecInfo = codecs.attr("CodecInfo");
object _sync_decode = make_function(sync_decode);
object _sync_encode = make_function(sync_encode);
return call< object >(CodecInfo.ptr(), _sync_encode, _sync_decode);
}
}
object distribution_search(string name)
{
if (name != "pep.distribution") {
return object();
}
else {
object codecs = import("codecs");
object CodecInfo = codecs.attr("CodecInfo");
object _distribution_decode = make_function(Distribution_decode);
object _distribution_encode = make_function(Distribution_encode);
return call< object >(CodecInfo.ptr(), _distribution_encode, _distribution_decode);
}
}
} // namespace PythonAdapter
} // namespace pEp {

25
src/pEp/native_pEp/message_api.hh

@ -6,12 +6,19 @@
#include "pEpmodule.hh"
namespace pEp {
namespace PythonAdapter {
Message encrypt_message(Message src, boost::python::list extra = boost::python::list(),
int enc_format = 4, int flags = 0);
boost::python::tuple decrypt_message(Message src, int flags=0);
PEP_color _color(int rating);
object sync_search(string name);
object distribution_search(string name);
}
}
namespace PythonAdapter {
Message encrypt_message(
Message src,
boost::python::list extra = boost::python::list(),
int enc_format = 4,
int flags = 0
);
boost::python::tuple decrypt_message(Message src, int flags=0);
PEP_color _color(int rating);
object sync_search(string name);
object distribution_search(string name);
} // namespace PythonAdapter
} // namespace pEp {

349
src/pEp/native_pEp/pEpmodule.cc

@ -1,6 +1,7 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
// System
#include <boost/python.hpp>
#include <boost/locale.hpp>
#include <string>
@ -8,180 +9,190 @@
#include <iomanip>
#include <mutex>
#include <pEp/Adapter.hh>
// Engine
#include <pEp/key_reset.h>
#include <pEp/message_api.h>
#include <pEp/sync_api.h>
#include <pEp/status_to_string.h>
// libpEpAdapter
#include <pEp/Adapter.hh>
#include <pEp/callback_dispatcher.hh>
#include <pEp/pEpLog.hh>
// local
#include "pEpmodule.hh"
#include "basic_api.hh"
#include "message_api.hh"
#include "user_interface.hh"
namespace pEp {
namespace PythonAdapter {
using namespace std;
// Adapter adapter(true);
void config_passive_mode(bool enable)
{
::config_passive_mode(pEp::Adapter::session(), enable);
}
void config_unencrypted_subject(bool enable)
{
::config_unencrypted_subject(pEp::Adapter::session(), enable);
}
void key_reset_user(string user_id, string fpr)
{
if (user_id == "")
throw invalid_argument("user_id required");
PEP_STATUS status = ::key_reset_user(pEp::Adapter::session(),
user_id.c_str(), fpr != "" ? fpr.c_str() : nullptr);
_throw_status(status);
}
void key_reset_user2(string user_id)
{
key_reset_user(user_id, "");
}
void key_reset_all_own_keys()
{
PEP_STATUS status = ::key_reset_all_own_keys(pEp::Adapter::session());
_throw_status(status);
}
scope *_scope = NULL;
static const char *version_string = "p≡p Python adapter version 0.3";
static string about()
{
string version = string(version_string) + "\np≡p version "
+ PEP_VERSION + "\n";
return version;
}
void _throw_status(PEP_STATUS status)
{
if (status == PEP_STATUS_OK)
return;
if (status >= 0x400 && status <= 0x4ff)
return;
if (status == PEP_OUT_OF_MEMORY)
throw bad_alloc();
if (status == PEP_ILLEGAL_VALUE)
throw invalid_argument("illegal value");
if (string(pEp_status_to_string(status)) == "unknown status code") {
stringstream build;
build << setfill('0') << "p≡p 0x" << setw(4) << hex << status;
throw runtime_error(build.str());
}
else {
throw runtime_error(pEp_status_to_string(status));
}
}
PEP_STATUS _ensure_passphrase(PEP_SESSION session, const char *fpr)
{
return PEP_STATUS_OK;
}
PEP_STATUS _messageToSend(::message *msg)
{
if (!_scope)
return PEP_SEND_FUNCTION_NOT_REGISTERED;
try {
object m = _scope->attr("messageToSend");
call< void >(m.ptr(), Message(msg));
}
catch (exception& e) { }
return PEP_STATUS_OK;
}
void messageToSend(Message msg) {
throw runtime_error("implement pEp.messageToSend(msg)");
}
namespace PythonAdapter {
using namespace std;
using namespace boost::python;
scope *_scope = NULL;
static const char *version_string = "p≡p Python adapter version 0.3";
void _init() {
pEpLog("called");
callback_dispatcher.add(_messageToSend, nullptr, nullptr, nullptr);
}
void config_passive_mode(bool enable)
{
::config_passive_mode(pEp::Adapter::session(), enable);
}
void config_unencrypted_subject(bool enable)
{
::config_unencrypted_subject(pEp::Adapter::session(), enable);
}
void key_reset_user(string user_id, string fpr)
{
if (user_id == "")
throw invalid_argument("user_id required");
PEP_STATUS status = ::key_reset_user(pEp::Adapter::session(),
user_id.c_str(), fpr != "" ? fpr.c_str() : nullptr);
_throw_status(status);
}
void key_reset_user2(string user_id)
{
key_reset_user(user_id, "");
}
void key_reset_all_own_keys()
{
PEP_STATUS status = ::key_reset_all_own_keys(pEp::Adapter::session());
_throw_status(status);
}
static string about()
{
string version = string(version_string) + "\np≡p version "
+ PEP_VERSION + "\n";
return version;
}
void _throw_status(PEP_STATUS status)
{
if (status == PEP_STATUS_OK)
return;
if (status >= 0x400 && status <= 0x4ff)
return;
if (status == PEP_OUT_OF_MEMORY)
throw bad_alloc();
if (status == PEP_ILLEGAL_VALUE)
throw invalid_argument("illegal value");
if (string(pEp_status_to_string(status)) == "unknown status code") {
stringstream build;
build << setfill('0') << "p≡p 0x" << setw(4) << hex << status;
throw runtime_error(build.str());
}
else {
throw runtime_error(pEp_status_to_string(status));
}
}
PEP_STATUS _ensure_passphrase(PEP_SESSION session, const char *fpr)
{
return PEP_STATUS_OK;
}
PEP_STATUS _messageToSend(::message *msg)
{
if (!_scope)
return PEP_SEND_FUNCTION_NOT_REGISTERED;
try {
object m = _scope->attr("messageToSend");
call< void >(m.ptr(), Message(msg));
}
catch (exception& e) { }
return PEP_STATUS_OK;
}
void messageToSend(Message msg) {
throw runtime_error("implement pEp.messageToSend(msg)");
}
// void do_sync_protocol()
// {
// ::do_sync_protocol(pEp::Adapter::session(), nullptr);
// }
void shutdown_sync()
{
pEp::Adapter::shutdown();
}
void shutdown_sync()
{
pEp::Adapter::shutdown();
}
void debug_color(int ansi_color)
{
::set_debug_color(pEp::Adapter::session(), ansi_color);
}
void debug_color(int ansi_color)
{
::set_debug_color(pEp::Adapter::session(), ansi_color);
}
void leave_device_group() {
::leave_device_group(pEp::Adapter::session());
}
void leave_device_group()
{
::leave_device_group(pEp::Adapter::session());
}
// void script_is_implementing_sync() {
// adapter.script_is_implementing_sync();
// }
bool is_sync_active() {
return pEp::Adapter::is_sync_running();
}
}
bool is_sync_active()
{
return pEp::Adapter::is_sync_running();
}
BOOST_PYTHON_MODULE(native_pEp)
{
using namespace boost::python;
using namespace boost::locale;
using namespace pEp::PythonAdapter;
docstring_options doc_options(true, false, false);
generator gen;
boost::locale::generator gen;
std::locale::global(gen(""));
_scope = new scope();
// Module init function called by pEp.init()
def("_init", _init);
_scope = new scope();
scope().attr("about") = about();
scope().attr("per_user_directory") = per_user_directory();
scope().attr("per_machine_directory") = per_machine_directory();
scope().attr("engine_version") = get_engine_version();
scope().attr("protocol_version") = get_protocol_version();
def("passive_mode", pEp::PythonAdapter::config_passive_mode,
def("passive_mode", config_passive_mode,
"do not attach pub keys to all messages");
def("unencrypted_subject", pEp::PythonAdapter::config_unencrypted_subject,
def("unencrypted_subject", config_unencrypted_subject,
"do not encrypt the subject of messages");
def("key_reset", pEp::PythonAdapter::key_reset_user,
def("key_reset", key_reset_user,
"reset the default database status for the user / keypair provided\n"
"This will effectively perform key_reset on each identity\n"
"associated with the key and user_id, if a key is provided, and for\n"
"each key (and all of their identities) if an fpr is not.");
def("key_reset", pEp::PythonAdapter::key_reset_user2,
def("key_reset", key_reset_user2,
"reset the default database status for the user / keypair provided\n"
"This will effectively perform key_reset on each identity\n"
"associated with the key and user_id, if a key is provided, and for\n"
"each key (and all of their identities) if an fpr is not.");
def("key_reset_all_own_keys", pEp::PythonAdapter::key_reset_all_own_keys,
def("key_reset_all_own_keys", key_reset_all_own_keys,
"revoke and mistrust all own keys, generate new keys for all\n"
"own identities, and opportunistically communicate key reset\n"
"information to people we have recently contacted.");
auto identity_class = class_<pEp::PythonAdapter::Identity>("Identity",
auto identity_class = class_<Identity>("Identity",
"Identity(address, username, user_id='', fpr='', comm_type=0, lang='en')\n"
"\n"
"represents a p≡p identity\n"
@ -204,12 +215,12 @@ BOOST_PYTHON_MODULE(native_pEp)
.def(boost::python::init<string, string, string, string>())
.def(boost::python::init<string, string, string, string, int>())
.def(boost::python::init<string, string, string, string, int, string>())
.def("__repr__", &pEp::PythonAdapter::Identity::_repr)
.def("__str__", &pEp::PythonAdapter::Identity::_str,
.def("__repr__", &Identity::_repr)
.def("__str__", &Identity::_str,
"string representation of this identity\n"
"following the pattern 'username < address >'\n"
)
.def("key_reset", &pEp::PythonAdapter::Identity::key_reset,
.def("key_reset", &Identity::key_reset,
boost::python::arg("fpr")=object(""),
"reset the default database status for the identity / keypair provided. If this\n"
"corresponds to the own user and a private key, also revoke the key, generate a\n"
@ -217,7 +228,7 @@ BOOST_PYTHON_MODULE(native_pEp)
"identity. If it does not, remove the key from the keyring; the key's status is\n"
"completely fresh on next contact from the partner.")
.def("key_mistrusted", &pEp::PythonAdapter::Identity::key_mistrusted,
.def("key_mistrusted", &Identity::key_mistrusted,
boost::python::arg("fpr")=object(""),
"If you want updated trust on the identity, you ll have"
"to call update_identity or myself respectively after this."
@ -227,42 +238,42 @@ BOOST_PYTHON_MODULE(native_pEp)
"will only undo the current identity's / it's user's default, not any"
"other identities which may be impacted (this will not affect most use cases)")
.def("enable_for_sync", &pEp::PythonAdapter::Identity::enable_for_sync,
.def("enable_for_sync", &Identity::enable_for_sync,
"Enable own identity for p≡p sync.\n\n"
"Only use this on own identities, which are used as accounts.\n")
.def("disable_for_sync", &pEp::PythonAdapter::Identity::disable_for_sync,
.def("disable_for_sync", &Identity::disable_for_sync,
"Disable own identity for p≡p sync.\n\n"
"Only use this on own identities, which are used as accounts.\n")
.add_property("address", (string(pEp::PythonAdapter::Identity::*)()) &pEp::PythonAdapter::Identity::address,
(void(pEp::PythonAdapter::Identity::*)(string)) &pEp::PythonAdapter::Identity::address,
.add_property("address", (string(Identity::*)()) &Identity::address,
(void(Identity::*)(string)) &Identity::address,
"email address or URI")
.add_property("fpr", (string(pEp::PythonAdapter::Identity::*)()) &pEp::PythonAdapter::Identity::fpr,
(void(pEp::PythonAdapter::Identity::*)(string)) &pEp::PythonAdapter::Identity::fpr,
.add_property("fpr", (string(Identity::*)()) &Identity::fpr,
(void(Identity::*)(string)) &Identity::fpr,
"key ID (full fingerprint, hex encoded)")
.add_property("user_id", (string(pEp::PythonAdapter::Identity::*)()) &pEp::PythonAdapter::Identity::user_id,
(void(pEp::PythonAdapter::Identity::*)(string)) &pEp::PythonAdapter::Identity::user_id,
.add_property("user_id", (string(Identity::*)()) &Identity::user_id,
(void(Identity::*)(string)) &Identity::user_id,
"ID of person associated or 'pEp_own_userId' if own identity")
.add_property("username", (string(pEp::PythonAdapter::Identity::*)()) &pEp::PythonAdapter::Identity::username,
(void(pEp::PythonAdapter::Identity::*)(string)) &pEp::PythonAdapter::Identity::username,
.add_property("username", (string(Identity::*)()) &Identity::username,
(void(Identity::*)(string)) &Identity::username,
"name in full of person associated")
.add_property("comm_type", (int(pEp::PythonAdapter::Identity::*)())
(PEP_comm_type(pEp::PythonAdapter::Identity::*)()) &pEp::PythonAdapter::Identity::comm_type,
(void(pEp::PythonAdapter::Identity::*)(int))
(void(pEp::PythonAdapter::Identity::*)(PEP_comm_type)) &pEp::PythonAdapter::Identity::comm_type,
.add_property("comm_type", (int(Identity::*)())
(PEP_comm_type(Identity::*)()) &Identity::comm_type,
(void(Identity::*)(int))
(void(Identity::*)(PEP_comm_type)) &Identity::comm_type,
"communication type, first rating level (p≡p internal)")
.add_property("lang", (string(pEp::PythonAdapter::Identity::*)()) &pEp::PythonAdapter::Identity::lang,
(void(pEp::PythonAdapter::Identity::*)(string)) &pEp::PythonAdapter::Identity::lang,
.add_property("lang", (string(Identity::*)()) &Identity::lang,
(void(Identity::*)(string)) &Identity::lang,
"ISO 639-1 language code")
.add_property("flags", (identity_flags_t(pEp::PythonAdapter::Identity::*)()) &pEp::PythonAdapter::Identity::flags,
(void(pEp::PythonAdapter::Identity::*)(identity_flags_t)) &pEp::PythonAdapter::Identity::flags,
.add_property("flags", (identity_flags_t(Identity::*)()) &Identity::flags,
(void(Identity::*)(identity_flags_t)) &Identity::flags,
"flags (p≡p internal)")
.add_property("rating", &pEp::PythonAdapter::Identity::rating, "rating of Identity")
.add_property("color", &pEp::PythonAdapter::Identity::color, "color of Identity as PEP_color")
.add_property("is_pEp_user", &pEp::PythonAdapter::Identity::is_pEp_user, "True if this is an identity of a pEp user")
.def("__deepcopy__", &pEp::PythonAdapter::Identity::deepcopy)
.def("update", &pEp::PythonAdapter::Identity::update, "update Identity")
.def("__copy__", &pEp::PythonAdapter::Identity::copy);
.add_property("rating", &Identity::rating, "rating of Identity")
.add_property("color", &Identity::color, "color of Identity as PEP_color")
.add_property("is_pEp_user", &Identity::is_pEp_user, "True if this is an identity of a pEp user")
.def("__deepcopy__", &Identity::deepcopy)
.def("update", &Identity::update, "update Identity")
.def("__copy__", &Identity::copy);
identity_class.attr("PEP_OWN_USERID") = "pEp_own_userId";
@ -313,7 +324,7 @@ BOOST_PYTHON_MODULE(native_pEp)
" mime_text text in Multipurpose Internet Mail Extensions format\n"
)
.def(boost::python::init<int>())
.def(boost::python::init<int, pEp::PythonAdapter::Identity *>())
.def(boost::python::init<int, Identity *>())
.def(boost::python::init<string>())
.def("__str__", &Message::_str,
"the string representation of a Message is it's MIME text"
@ -345,13 +356,13 @@ BOOST_PYTHON_MODULE(native_pEp)
.add_property("recv", (time_t(Message::*)()) &Message::recv,
(void(Message::*)(time_t)) &Message::recv,
"time when message was received in UTC seconds since epoch")
.add_property("from_", (pEp::PythonAdapter::Identity(Message::*)()) &Message::from,
.add_property("from_", (Identity(Message::*)()) &Message::from,
(void(Message::*)(object)) &Message::from,
"identity where message is from")
.add_property("to", (boost::python::list(Message::*)()) &Message::to,
(void(Message::*)(boost::python::list)) &Message::to,
"list of identities message is going to")
.add_property("recv_by", (pEp::PythonAdapter::Identity(Message::*)()) &Message::recv_by,
.add_property("recv_by", (Identity(Message::*)()) &Message::recv_by,
(void(Message::*)(object)) &Message::recv_by,
"identity where message was received by")
.add_property("cc", (boost::python::list(Message::*)()) &Message::cc,
@ -414,19 +425,19 @@ BOOST_PYTHON_MODULE(native_pEp)
// basic API and key management API
def("update_identity", &pEp::PythonAdapter::update_identity,
def("update_identity", &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", &pEp::PythonAdapter::myself,
def("myself", &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", &pEp::PythonAdapter::trust_personal_key,
def("trust_personal_key", &trust_personal_key,
"trust_personal_key(ident)\n"
"\n"
"mark a key as trusted with a person\n"
@ -437,44 +448,44 @@ BOOST_PYTHON_MODULE(native_pEp)
.value("PEP_idf_list", PEP_idf_list)
.value("PEP_idf_devicegroup", PEP_idf_devicegroup);
def("set_identity_flags", &pEp::PythonAdapter::set_identity_flags,
def("set_identity_flags", &set_identity_flags,
"set_identity_flags(ident, flags)\n"
"\n"
"set identity flags\n"
);
def("unset_identity_flags", &pEp::PythonAdapter::unset_identity_flags,
def("unset_identity_flags", &unset_identity_flags,
"unset_identity_flags(ident, flags)\n"
"\n"
"unset identity flags\n"
);
def("key_reset_trust", &pEp::PythonAdapter::key_reset_trust,
def("key_reset_trust", &key_reset_trust,
"key_reset_trust(ident)\n"
"\n"
"reset trust bit or explicitly mistrusted status for an identity and "
"its accompanying key/user_id pair\n"
);
def("import_key", &pEp::PythonAdapter::import_key,
def("import_key", &import_key,
"private_key_list = import_key(key_data)\n"
"\n"
"import key(s) from key_data\n"
);
def("export_key", &pEp::PythonAdapter::export_key,
def("export_key", &export_key,
"key_data = export_key(identity)\n"
"\n"
"export key(s) of identity\n"
);
def("export_secret_key", &pEp::PythonAdapter::export_secret_key,
def("export_secret_key", &export_secret_key,
"key_data = export_seret_key(identity)\n"
"\n"
"export secret key(s) of identity\n"
);
def("set_own_key", &pEp::PythonAdapter::set_own_key,
def("set_own_key", &set_own_key,
"set_own_key(me, fpr)\n"
"\n"
"mark a key as an own key, and make it the default key\n"
@ -534,7 +545,7 @@ BOOST_PYTHON_MODULE(native_pEp)
// messageToSend()
def("messageToSend", &pEp::PythonAdapter::messageToSend,
def("messageToSend", &messageToSend,
"messageToSend(msg)\n"
"\n"
"override pEp.messageToSend(msg) with your own implementation\n"
@ -577,41 +588,40 @@ BOOST_PYTHON_MODULE(native_pEp)
// " result -1: cancel, 0: accepted, 1: rejected\n"
// " identities list of identities to share or None for all\n"
// "\n"
// "call to deliver the handshake result of the handshake dialog")
// ;
// "call to deliver the handshake result of the handshake dialog");
// TODO: Replace with start_sync()
// def("do_sync_protocol", &pEp::PythonAdapter::do_sync_protocol,
// def("do_sync_protocol", &do_sync_protocol,
// "do_sync_protocol()\n"
// "\n"
// "in case of an explicit sync thread instead of a single threaded\n"
// "implementation call this function in your sync thread\n"
// );
def("shutdown_sync", &pEp::PythonAdapter::shutdown_sync,
def("shutdown_sync", &shutdown_sync,
"shutdown_sync()\n"
"\n"
"call this from another thread to shut down the sync thread\n"
);
def("debug_color", &pEp::PythonAdapter::debug_color,
def("debug_color", &debug_color,
"for debug builds set ANSI color value");
def("leave_device_group", &pEp::PythonAdapter::leave_device_group,
def("leave_device_group", &leave_device_group,
"leave_device_group()\n"
"\n"
"call this for a grouped device, which should leave\n"
);
// def("script_is_implementing_sync", &pEp::PythonAdapter::script_is_implementing_sync,
// def("script_is_implementing_sync", &script_is_implementing_sync,
// "script_is_implementing_sync()\n"
// "\n"
// "call this in case the Python script is implementing sync to make\n"
// "is_sync_active() working\n"
// );
def("is_sync_active", &pEp::PythonAdapter::is_sync_active,
def("is_sync_active", &is_sync_active,
"is_sync_active()\n"
"\n"
"True if sync is active, False otherwise\n"
@ -622,3 +632,6 @@ BOOST_PYTHON_MODULE(native_pEp)
call< object >(((object)(import("codecs").attr("register"))).ptr(), make_function(sync_search));
call< object >(((object)(import("codecs").attr("register"))).ptr(), make_function(distribution_search));
}
} // namespace PythonAdapter
} // namespace pEp

33
src/pEp/native_pEp/pEpmodule.hh

@ -1,21 +1,26 @@
#pragma once
// Engine
#include <pEp/pEpEngine.h>
// local
#include "message.hh"
namespace pEp {
namespace PythonAdapter {
extern string device_name;
void config_passive_mode(bool enable);
void config_unencrypted_subject(bool enable);
void key_reset_user(string user_id, string fpr);
void key_reset_all_own_keys();
void _throw_status(PEP_STATUS status);
void messageToSend(Message msg);
PEP_STATUS _messageToSend(::message *msg);
PEP_STATUS _ensure_passphrase(PEP_SESSION session, const char *fpr);
// void do_sync_protocol();
// extern Adapter adapter;
}
}
namespace PythonAdapter {
extern string device_name;
void config_passive_mode(bool enable);
void config_unencrypted_subject(bool enable);
void key_reset_user(string user_id, string fpr);
void key_reset_all_own_keys();
void _throw_status(PEP_STATUS status);
void messageToSend(Message msg);
PEP_STATUS _messageToSend(::message *msg);
PEP_STATUS _ensure_passphrase(PEP_SESSION session, const char *fpr);
// void do_sync_protocol();
// extern Adapter adapter;
} // namespace PythonAdapter
} // namespace pEp {

296
src/pEp/native_pEp/str_attr.cc

@ -1,180 +1,184 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
// System
#include <cstdlib>
#include <boost/python.hpp>
#include <boost/locale.hpp>
#include <cstdlib>
// local
#include "str_attr.hh"
namespace pEp {
namespace utility {
using namespace std;
using namespace boost::locale;
namespace PythonAdapter {
using namespace std;
using namespace boost::python;
using namespace boost::locale;
object repr(object s)
{
return s.attr("__repr__")();
}
object repr(object s)
{
return s.attr("__repr__")();
}
string repr(string s)
{
str _s = s.c_str();
object _r = _s.attr("__repr__")();
string r = extract< string >(_r);
return r;
}
string repr(string s)
{
str _s = s.c_str();
object _r = _s.attr("__repr__")();
string r = extract< string >(_r);
return r;
}
string str_attr(char *&str)
{
if (!str)
return string("");
return string(str);
}
string str_attr(char *&str)
{
if (!str)
return string("");
return string(str);
}
void str_attr(char *&str, string value)
{
string normalized = normalize(value, norm_nfc);
free(str);
str = strdup(normalized.c_str());
if (!str)
throw bad_alloc();
}
void str_attr(char *&str, string value)
{
string normalized = normalize(value, norm_nfc);
free(str);
str = strdup(normalized.c_str());
if (!str)
throw bad_alloc();
}
time_t timestamp_attr(timestamp *&ts)
{
if (!ts)
return 0;
time_t timestamp_attr(timestamp *&ts)
{
if (!ts)
return 0;
return timegm(ts);
}
return timegm(ts);
}
void timestamp_attr(timestamp *&ts, time_t value)
{
free_timestamp(ts);
ts = new_timestamp(value);
}
void timestamp_attr(timestamp *&ts, time_t value)
{
free_timestamp(ts);
ts = new_timestamp(value);
}
boost::python::list strlist_attr(stringlist_t *&sl)
{
boost::python::list result;
boost::python::list strlist_attr(stringlist_t *&sl)
{
boost::python::list result;
for (stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) {
string s(_sl->value);
result.append(object(s));
}
for (stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) {
string s(_sl->value);
result.append(object(s));
}
return result;
}
return result;
void strlist_attr(stringlist_t *&sl, boost::python::list value)
{
stringlist_t *_sl = new_stringlist(NULL);
if (!_sl)
throw bad_alloc();
stringlist_t *_s = _sl;
for (int i=0; i<len(value); i++) {
extract< string > extract_string(value[i]);
if (!extract_string.check()) {
free_stringlist(_sl);
}
void strlist_attr(stringlist_t *&sl, boost::python::list value)
{
stringlist_t *_sl = new_stringlist(NULL);
if (!_sl)
throw bad_alloc();
stringlist_t *_s = _sl;
for (int i=0; i<len(value); i++) {
extract< string > extract_string(value[i]);
if (!extract_string.check()) {
free_stringlist(_sl);
}
string s = extract_string();
s = normalize(s, norm_nfc);
_s = stringlist_add(_s, s.c_str());
if (!_s) {
free_stringlist(_sl);
throw bad_alloc();
}
}
free_stringlist(sl);
sl = _sl;
string s = extract_string();
s = normalize(s, norm_nfc);
_s = stringlist_add(_s, s.c_str());
if (!_s) {
free_stringlist(_sl);
throw bad_alloc();
}
}
dict strdict_attr(stringpair_list_t *&spl)
{
dict result;
free_stringlist(sl);
sl = _sl;
}
for (stringpair_list_t *_spl = spl; _spl && _spl->value; _spl =
_spl->next) {
stringpair_t *p = _spl->value;
if (p->key && p->value) {
string key(p->key);
string value(p->value);
dict strdict_attr(stringpair_list_t *&spl)
{
dict result;
result[key] = value;
}
}
for (stringpair_list_t *_spl = spl; _spl && _spl->value; _spl =
_spl->next) {
stringpair_t *p = _spl->value;
if (p->key && p->value) {
string key(p->key);
string value(p->value);
return result;
result[key] = value;
}
}
void strdict_attr(stringpair_list_t *&spl, dict value)
{
stringpair_list_t *_spl = new_stringpair_list(NULL);
if (!_spl)
throw bad_alloc();
stringpair_list_t *_s = _spl;
for (int i=0; i<len(value); i++) {
extract< string > extract_key(value.keys()[i]);
extract< string > extract_value(value.values()[i]);
if (!(extract_key.check() && extract_value.check()))
free_stringpair_list(_spl);
string key = extract_key();
key = normalize(key, norm_nfc);
string _value = extract_value();
_value = normalize(_value, norm_nfc);
stringpair_t *pair = new_stringpair(key.c_str(), _value.c_str());
if (!pair) {
free_stringpair_list(_spl);
throw bad_alloc();
}
_s = stringpair_list_add(_s, pair);
if (!_s) {
free_stringpair_list(_spl);
throw bad_alloc();
}
}
free_stringpair_list(spl);
spl = _spl;
}
return result;
}
stringlist_t *to_stringlist(boost::python::list l)
{
stringlist_t *result = new_stringlist(NULL);
if (!result)
throw bad_alloc();
stringlist_t *_s = result;
for (int i=0; i<len(l); i++) {
extract< string > extract_string(l[i]);
if (!extract_string.check())
free_stringlist(result);
string s = extract_string();
_s = stringlist_add(_s, s.c_str());
if (!_s) {
free_stringlist(result);
throw bad_alloc();
}
}
return result;
void strdict_attr(stringpair_list_t *&spl, dict value)
{
stringpair_list_t *_spl = new_stringpair_list(NULL);
if (!_spl)
throw bad_alloc();
stringpair_list_t *_s = _spl;
for (int i=0; i<len(value); i++) {
extract< string > extract_key(value.keys()[i]);
extract< string > extract_value(value.values()[i]);
if (!(extract_key.check() && extract_value.check()))
free_stringpair_list(_spl);
string key = extract_key();
key = normalize(key, norm_nfc);
string _value = extract_value();
_value = normalize(_value, norm_nfc);
stringpair_t *pair = new_stringpair(key.c_str(), _value.c_str());
if (!pair) {
free_stringpair_list(_spl);
throw bad_alloc();
}
_s = stringpair_list_add(_s, pair);
if (!_s) {
free_stringpair_list(_spl);
throw bad_alloc();
}
}
boost::python::list from_stringlist(const stringlist_t *sl)
{
boost::python::list result;
for (const stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) {
string s = _sl->value;
result.append(s);
}
return result;
free_stringpair_list(spl);
spl = _spl;
}
stringlist_t *to_stringlist(boost::python::list l)
{
stringlist_t *result = new_stringlist(NULL);
if (!result)
throw bad_alloc();
stringlist_t *_s = result;
for (int i=0; i<len(l); i++) {
extract< string > extract_string(l[i]);
if (!extract_string.check())
free_stringlist(result);
string s = extract_string();
_s = stringlist_add(_s, s.c_str());
if (!_s) {
free_stringlist(result);
throw bad_alloc();
}
}
return result;
}
boost::python::list from_stringlist(const stringlist_t *sl)
{
boost::python::list result;
for (const stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) {
string s = _sl->value;
result.append(s);
}
return result;
}
} // namespace PythonAdapter
} // namespace pEp {

38
src/pEp/native_pEp/str_attr.hh

@ -3,35 +3,39 @@
#pragma once
// System
#include <string>
// Engine
#include <pEp/pEpEngine.h>
#include <pEp/timestamp.h>
#include <pEp/stringlist.h>
#include <pEp/stringpair.h>
namespace pEp {
namespace utility {
using namespace std;
using namespace boost::python;
namespace PythonAdapter {
using std::string;
using boost::python::object;
using boost::python::dict;
object repr(object s);
string repr(string s);
object repr(object s);
string repr(string s);
string str_attr(char *&str);
void str_attr(char *&str, string value);
string str_attr(char *&str);
void str_attr(char *&str, string value);
time_t timestamp_attr(timestamp *&ts);
void timestamp_attr(timestamp *&ts, time_t value);
time_t timestamp_attr(timestamp *&ts);
void timestamp_attr(timestamp *&ts, time_t value);
boost::python::list strlist_attr(stringlist_t *&sl);
void strlist_attr(stringlist_t *&sl, boost::python::list value);
boost::python::list strlist_attr(stringlist_t *&sl);
void strlist_attr(stringlist_t *&sl, boost::python::list value);
dict strdict_attr(stringpair_list_t *&spl);
void strdict_attr(stringpair_list_t *&spl, dict value);
dict strdict_attr(stringpair_list_t *&spl);
void strdict_attr(stringpair_list_t *&spl, dict value);
stringlist_t *to_stringlist(boost::python::list l);
boost::python::list from_stringlist(const stringlist_t *sl);
}
}
stringlist_t *to_stringlist(boost::python::list l);
boost::python::list from_stringlist(const stringlist_t *sl);
} // namespace PythonAdapter
} // namespace pEp {

199
src/pEp/native_pEp/user_interface.cc

@ -1,124 +1,129 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
// System
#include <cassert>
// local
#include "user_interface.hh"
namespace pEp {
namespace PythonAdapter {
UserInterface *UserInterface::_ui = nullptr;
UserInterface::UserInterface()
{
if (_ui)
throw runtime_error("only one UserInterface thread allowed");
_ui = this;
}
namespace PythonAdapter {
UserInterface::~UserInterface()
{
_ui = nullptr;
}
UserInterface *UserInterface::_ui = nullptr;
UserInterface_callback::UserInterface_callback(PyObject *self) :
UserInterface(), _self(self)
{
// adapter.ui_object(self);
PEP_STATUS status = ::register_sync_callbacks(pEp::Adapter::session(),
(void *) this, _notifyHandshake, retrieve_next_sync_event);
assert(status == PEP_STATUS_OK);
if (status)
_throw_status(status);
}
UserInterface::UserInterface()
{
if (_ui)
throw runtime_error("only one UserInterface thread allowed");
_ui = this;
}
UserInterface_callback::~UserInterface_callback()
{
::unregister_sync_callbacks(pEp::Adapter::session());
}
UserInterface::~UserInterface()
{
_ui = nullptr;
}
PEP_STATUS UserInterface::_notifyHandshake(
pEp_identity *me, pEp_identity *partner,
sync_handshake_signal signal
)
{
if (!(me && partner))
return PEP_ILLEGAL_VALUE;
UserInterface_callback::UserInterface_callback(PyObject *self) :
UserInterface(), _self(self)
{
// adapter.ui_object(self);
PEP_STATUS status = ::register_sync_callbacks(pEp::Adapter::session(),
(void *) this, _notifyHandshake, retrieve_next_sync_event);
assert(status == PEP_STATUS_OK);
if (status)
_throw_status(status);
}
auto that = dynamic_cast< UserInterface_callback * >(_ui);
that->notifyHandshake(Identity(me), Identity(partner), signal);
UserInterface_callback::~UserInterface_callback()
{
::unregister_sync_callbacks(pEp::Adapter::session());
}
return PEP_STATUS_OK;
}
PEP_STATUS UserInterface::_notifyHandshake(
pEp_identity *me, pEp_identity *partner,
sync_handshake_signal signal
)
{
if (!(me && partner))
return PEP_ILLEGAL_VALUE;
void UserInterface::deliverHandshakeResult(int result, object identities)
{
identity_list *shared_identities = nullptr;
if (identities != boost::python::api::object() &&
boost::python::len(identities)) {
shared_identities = new_identity_list(nullptr);
if (!shared_identities)
throw bad_alloc();
auto that = dynamic_cast< UserInterface_callback * >(_ui);
that->notifyHandshake(Identity(me), Identity(partner), signal);
try {
identity_list *si = shared_identities;
for (int i=0; i < boost::python::len(identities); ++i) {
Identity ident = extract< Identity >(identities[i]);
si = identity_list_add(si, ident);
if (!si)
throw bad_alloc();
}
}
catch (exception& ex) {
free_identity_list(shared_identities);
throw ex;
}
}
return PEP_STATUS_OK;
}
void UserInterface::deliverHandshakeResult(int result, object identities)
{
identity_list *shared_identities = nullptr;
if (identities != boost::python::api::object() &&
boost::python::len(identities)) {
shared_identities = new_identity_list(nullptr);
if (!shared_identities)
throw bad_alloc();
PEP_STATUS status = ::deliverHandshakeResult(pEp::Adapter::session(),
(sync_handshake_result) result, shared_identities);
try {
identity_list *si = shared_identities;
for (int i=0; i < boost::python::len(identities); ++i) {
Identity ident = extract< Identity >(identities[i]);
si = identity_list_add(si, ident);
if (!si)
throw bad_alloc();
}
}
catch (exception& ex) {
free_identity_list(shared_identities);
_throw_status(status);
throw ex;
}
}
PEP_rating UserInterface::get_key_rating_for_user(string user_id, string fpr)
{
PEP_rating result;
PEP_STATUS status =
::get_key_rating_for_user(pEp::Adapter::session(),
user_id.c_str(), fpr.c_str(), &result);
_throw_status(status);
return result;
}
PEP_STATUS status = ::deliverHandshakeResult(pEp::Adapter::session(),
(sync_handshake_result) result, shared_identities);
free_identity_list(shared_identities);
_throw_status(status);
}
// SYNC_EVENT UserInterface::retrieve_next_sync_event(void *management, unsigned threshold)
// {
// time_t started = time(nullptr);
// bool timeout = false;
PEP_rating UserInterface::get_key_rating_for_user(string user_id, string fpr)
{
PEP_rating result;
PEP_STATUS status =
::get_key_rating_for_user(pEp::Adapter::session(),
user_id.c_str(), fpr.c_str(), &result);
_throw_status(status);
return result;
}
//SYNC_EVENT UserInterface::retrieve_next_sync_event(void *management, unsigned threshold)
//{
// time_t started = time(nullptr);
// bool timeout = false;
//
// while (adapter.queue().empty()) {
// int i = 0;
// ++i;
// if (i > 10) {
// if (time(nullptr) > started + threshold) {
// timeout = true;
// break;
// }
// i = 0;
// }
// nanosleep((const struct timespec[]){{0, 100000000L}}, NULL);
// while (adapter.queue().empty()) {
// int i = 0;
// ++i;
// if (i > 10) {
// if (time(nullptr) > started + threshold) {
// timeout = true;
// break;
// }
// i = 0;
// }
// nanosleep((const struct timespec[]){{0, 100000000L}}, NULL);
// }
//
// if (timeout)
// return new_sync_timeout_event();
// if (timeout)
// return new_sync_timeout_event();
//
// return adapter.queue().pop_front();
// }
// return adapter.queue().pop_front();
//}
void UserInterface_callback::notifyHandshake(
Identity me, Identity partner, sync_handshake_signal signal)
{
call_method< void >(_self, "notifyHandshake", me, partner, signal);
}
}
void UserInterface_callback::notifyHandshake(
Identity me, Identity partner, sync_handshake_signal signal)
{
call_method< void >(_self, "notifyHandshake", me, partner, signal);
}
} // namespace PythonAdapter
} // namespace pEp {

81
src/pEp/native_pEp/user_interface.hh

@ -3,51 +3,58 @@
#pragma once
// System
#include <csetjmp>
// Engine
#include <pEp/sync_api.h>
#include <pEp/message_api.h>
// local
#include "pEpmodule.hh"
namespace pEp {
namespace PythonAdapter {
class UserInterface {
static UserInterface *_ui;
public:
UserInterface();
virtual ~UserInterface();
virtual void notifyHandshake(
pEp::PythonAdapter::Identity me,
pEp::PythonAdapter::Identity partner,
sync_handshake_signal signal)
{
throw runtime_error("override this method");
}
virtual void deliverHandshakeResult(int result, object identities);
PEP_rating get_key_rating_for_user(string user_id, string fpr);
protected:
static PEP_STATUS _notifyHandshake(pEp_identity *me,
pEp_identity *partner, sync_handshake_signal signal);
static SYNC_EVENT retrieve_next_sync_event(void *management, unsigned threshold);
};
class UserInterface_callback : public UserInterface {
PyObject *_self;
public:
UserInterface_callback(PyObject *self);
~UserInterface_callback();
void notifyHandshake(
pEp::PythonAdapter::Identity me,
pEp::PythonAdapter::Identity partner,
sync_handshake_signal signal);
};
namespace PythonAdapter {
class UserInterface {
private:
static UserInterface *_ui;
public:
UserInterface();
virtual ~UserInterface();
virtual void notifyHandshake(
Identity me,
Identity partner,
sync_handshake_signal signal)
{
throw runtime_error("override this method");
}
}
virtual void deliverHandshakeResult(int result, object identities);
PEP_rating get_key_rating_for_user(string user_id, string fpr);
protected:
static PEP_STATUS _notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal);
static SYNC_EVENT retrieve_next_sync_event(void *management, unsigned threshold);
};
class UserInterface_callback : public UserInterface {
private:
PyObject *_self;
public:
UserInterface_callback(PyObject *self);
~UserInterface_callback();
void notifyHandshake(
Identity me,
Identity partner,
sync_handshake_signal signal
);
};
} // namespace PythonAdapter
} // namespace pEp {

1
test/pyadpt-81.py

@ -3,4 +3,5 @@
import pEp
dir(pEp)
pEp.is_sync_active()
Loading…
Cancel
Save