parent
07d2130bf0
commit
50ebe60221
@ -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 {
|
||||
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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) {
|
||||