Compare commits

...

22 Commits

Author SHA1 Message Date
heck 16e9bda15f sphinx doc - config and module doc pEp._gen / pEp._pEp
2 years ago
heck 348fa8f2f9 make clean
2 years ago
heck 8e1898446e gitignore
2 years ago
heck da1d3a8347 codegen - add enigne functions from message.h
2 years ago
heck 103208ea95 add pybind11 to setup-requires
2 years ago
heck 7a84853814 build - get pybind includes from pybind module
2 years ago
heck d87fd19652 gitignore generated debug files
2 years ago
heck 784653df6f Half the adapter generated, strike \o/!
2 years ago
heck 6a1d302821 _gen fix Makefiles
2 years ago
heck dc0b769136 _gen Add PEP_SESSION
2 years ago
heck 119effbfdb gen log_event
2 years ago
heck 7b4ba8b4c4 Makefile
2 years ago
heck b153ce3c7a Makefile - fix static vs dynamic linking options
2 years ago
heck 2e138e1190 introduce pEpACIDgen - Abstract C Interface Definition Generator
2 years ago
heck 0792869686 suitable name for the generated extension module
2 years ago
heck c56b3b40f3 Makefile based build for C++ parts only
2 years ago
heck 19b2ebb18d Move common includes, namespace aliases etc... to adapter_main.hh/.cc,
2 years ago
heck 0e896bf36c namespace cleanup - replace all "using namespace" with namspace aliases (except std in impl files.)
2 years ago
heck 0e893624c9 formatting fornatting - breakfast and lunch - dinner and brunch :)
2 years ago
heck 63e830040c Mark all symbols from the pEpEngine with explicit global namespace. (e.g: ::pEp_stuff).
2 years ago
heck 688fff5667 Add Makefile based build for _pEp native module
2 years ago
heck 8aa36d9f95 pyBind11 evaluation - parallel mode with boost.python
2 years ago

11
.gitignore vendored

@ -47,4 +47,13 @@ __pycache__/
.DS_store
# pEpACIDgen generated files
/src/pEp/_gen/gen/adapter_main.hh.acid.json
/src/pEp/_gen/gen/adapter_main.hh.acid.yml
/src/pEp/_gen/gen/adapter_main.hh.ast.json
/src/pEp/_gen/gen/py_module.pybind11
/src/pEp/_gen/gen/py_module.yml2
/src/pEp/_gen.cpython-38-darwin.so
/src/pEp/_pEp.cpython-38-darwin.so
/src/pEp/_gen/pEpModule.o
/src/pEp/_gen/_gen.so

@ -3,12 +3,20 @@ include Makefile.conf
.PHONY: all compile compile-inplace dist dist-egg dist-whl install install-user venv envtest install-test test develop docs clean clean-all clean-docs
all: dist
# Install pEpACIDgen from local repo clone, not from pypi
install-pepacidgen:
pip3 install -r requirements.txt --find-links ../pEpACIDgen/dist
# Build
# =====
compile:
gen: install-pepacidgen
$(MAKE) -C src/pEp/_gen gen
compile: gen
python3 setup.py build_ext $(DEBUG_OPT) $(PREFIX_OPT)
compile-inplace:
compile-inplace: gen
python3 setup.py build_ext $(DEBUG_OPT) $(PREFIX_OPT) --inplace
# Packaging
@ -57,8 +65,6 @@ envtest:
install-test: compile
pip3 install .[test]
# TODO: maybe use setup.py test?
# --forked, because every test needs a separate process, see PYADPT-100
test:
pytest
@ -80,6 +86,7 @@ clean-all: clean
rm -rf $(VENV_DIR)
clean: clean-docs
$(MAKE) -C src/pEp/_gen clean-all
rm -rf $(BUILD_DIR)
rm -rf $(DIST_DIR)
rm -rf $(PYTHON_ARTIFACTS)
@ -88,3 +95,14 @@ clean: clean-docs
clean-docs:
make clean -C docs/
# Makefile based build of C++ parts only
# ======================================
makefile-build:
$(MAKE) -C src/pEp/_pEp
$(MAKE) -C src/pEp/_gen
makefile-clean:
$(MAKE) -C src/pEp/_pEp clean
$(MAKE) -C src/pEp/_gen clean

@ -5,6 +5,7 @@ BUILD_DIR = ./build
DIST_DIR = ./dist
VERSION_FILE = ./src/pEp/__version__.py
BUILD_INPLACE = ./src/pEp/_pEp.cpython-38-darwin.so
BUILD_INPLACE += ./src/pEp/_gen.cpython-38-darwin.so
PYTHON_ARTIFACTS += ./.eggs
PYTHON_ARTIFACTS += ./src/pEp.egg-info
PYTHON_ARTIFACTS += ./.pytest_cache

@ -0,0 +1,8 @@
Module pEp._gen
---------------
.. automodule:: pEp._gen
:members:
:imported-members:
:undoc-members:
:show-inheritance:

@ -0,0 +1,7 @@
Module pEp._pEp
---------------
.. automodule:: pEp._pEp
:members:
:imported-members:
:undoc-members:
:show-inheritance:

@ -1,12 +1,7 @@
pEp package
===========
Module contents
---------------
Module pEp
----------
.. automodule:: pEp
:members:
:imported-members:
:undoc-members:
:show-inheritance:

@ -92,7 +92,7 @@ html_theme = "nature"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
#html_static_path = ["_static"]
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.

@ -13,6 +13,9 @@ Welcome to pEpPythonAdapter's documentation!
install
software_using
api/pEp
api/pEp._pEp
api/pEp._gen
Indices and tables
==================

@ -5,7 +5,8 @@
requires =[
"setuptools >=39.2.0",
"setuptools_scm >= 4.1.2",
"wheel >= 0.35.1" ]
"wheel >= 0.35.1",
"pybind11 >= 2.6.2" ]
build-backend = "setuptools.build_meta"

@ -0,0 +1,2 @@
pEpACIDgen
pyBind11

@ -35,6 +35,8 @@ setup_requires =
setuptools >=39.2.0
setuptools_scm >= 4.1.2
wheel >= 0.35.1
pybind11 >= 2.6.2
[options.extras_require]
# To install these dependencies, run pip install .[test]
test =

@ -7,7 +7,6 @@
from __future__ import print_function
import sys
import os
from os import environ
from os.path import join
@ -174,6 +173,14 @@ class BuildExtCommand(build_ext):
module_pEp.libraries = libs
module_pEp.extra_compile_args = compile_flags
global module_gen
module_gen.include_dirs = includes
import pybind11
module_gen.include_dirs += [pybind11.commands.get_include()]
module_gen.library_dirs = libdirs
# module_gen.libraries = libs
module_gen.extra_compile_args = compile_flags
pEpLog("Include Dirs:", module_pEp.include_dirs)
pEpLog("Libs Dirs:", module_pEp.library_dirs)
pEpLog("Libraries:", module_pEp.libraries)
@ -195,6 +202,7 @@ if sys.version_info[0] < 3:
module_pEp = Extension(
'pEp._pEp',
sources=[
'src/pEp/_pEp/adapter_main.cc',
'src/pEp/_pEp/pEpmodule.cc',
'src/pEp/_pEp/basic_api.cc',
'src/pEp/_pEp/identity.cc',
@ -205,11 +213,19 @@ module_pEp = Extension(
],
)
module_gen = Extension(
'pEp._gen',
sources=[
'src/pEp/_gen/pEpmodule.cc',
],
)
# "MAIN" Function
setup(
package_dir={'': 'src'},
packages=['pEp'],
ext_modules=[module_pEp],
ext_modules=[module_pEp, module_gen],
cmdclass={
'build_ext': BuildExtCommand,
},

@ -0,0 +1,16 @@
HERE:=$(dir $(lastword $(MAKEFILE_LIST)))
-include $(HERE)../../local.conf
TARGET_PEP=_pEp.so
TARGET_GEN=_gen.so
# General Build settings
CXX=g++
CXXFLAGS+=-std=c++11 -g
INCLUDES+=-I$(PREFIX)/include
INCLUDES+=-I/opt/local/Library/Frameworks/Python.framework/Versions/3.8/include/python3.8
LIB_DIRS=-L$(PREFIX)/lib
LIB_DIRS+=-L/opt/local/lib
LIBS=-lpEpEngine -lpEpAdapter
LDFLAGS+=-undefined dynamic_lookup

@ -25,10 +25,12 @@ except ImportError:
# Imports all symbols EXCEPT the ones beginning with underscore
from ._pEp import *
from ._gen import *
# import the native module into the current namespace because we also need to access the names beginning
# with an underscore (of _pEp), but we dont want to import them into this module
import pEp._pEp
import pEp._gen
# Executed on module import
def init():

@ -0,0 +1,46 @@
include Makefile.conf
TARGET=_gen.so
# Swap here, for static vs dyn linking
TARGET_MODULE_DYN=$(TARGET)
TARGET_MODULE_STATIC=
CXX=clang
CXXFLAGS+=-std=c++11 -g
SRCS+=$(wildcard *.cc)
OBJS+=$(SRCS:.cc=.o)
CXXFLAGS+=$(INCLUDES)
LDFLAGS_DYN+=-undefined dynamic_lookup $(LIBS_PATH) $(LIBS)
LDFLAGS_STATIC+=-undefined dynamic_lookup
$(info -----BUILD INFO----)
$(info SRCS $(SRCS))
$(info OBJS $(OBJS))
.PHONY: all gen gen-pybind module_dyn module_static clean
all: gen compile
gen:
$(MAKE) -C gen
gen-pybind:
$(MAKE) -C gen pybind
compile: $(TARGET)
$(TARGET_MODULE_DYN) : $(OBJS)
$(CXX) $(LDFLAGS_DYN) -o $@ $^
$(TARGET_MODULE_STATIC) : $(OBJS) $(LIBS_STATIC)
$(CXX) $(LDFLAGS_STATIC) -o $@ $^
clean:
rm -f $(TARGET)
rm -f $(OBJS)
clean-all: clean
$(MAKE) -C gen clean

@ -0,0 +1,12 @@
# pyBind11 and python headers
INCLUDES+=$(shell pybind11-config --includes)
# example lib
INCLUDES+=-I/Users/heck/local-default/include/
# static lib (.a)
#LIBS_STATIC+=/Users/heck/local-default/include/
# dynamic lib (.so)
LIBS+=-lpEpEngine
LIBS_PATH+=-L/Users/heck/local-default/lib

@ -0,0 +1,40 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
#ifndef ADAPTER_MAIN_HH
#define ADAPTER_MAIN_HH
// Use only if cant be avoided
//#include <pEp/stringlist.h>
/// =======
#include <pEp/pEpEngine.h>
//// Engine
////pEp-API
#include <pEp/keymanagement.h>
#include <pEp/message_api.h>
#include <pEp/sync_api.h>
#include <pEp/distribution_codec.h>
#include <pEp/sync_codec.h>
/// =======
// #include <pEp/identity_list.h>
// #include <pEp/key_reset.h>
// #include <pEp/mime.h>
// #include <pEp/message.h>
// #include <pEp/sync_codec.h>
// #include <pEp/distribution_codec.h>
// #include <pEp/timestamp.h>
// #include <pEp/stringpair.h>
// libpEpAdapter
/// =======
//#include <pEp/Adapter.hh>
//#include <pEp/callback_dispatcher.hh>
/// =======
// #include <pEp/status_to_string.hh>
// #include <pEp/pEpLog.hh>
#endif // ADAPTER_MAIN_HH

@ -0,0 +1,35 @@
include ../Makefile.conf
YML2_FILE=py_module.yml2
YSL2_FILE=$(shell pEp_acid_gen-config)
PYBIND11_FILE=py_module.pybind11
DEBUG_AST_FILE=adapter_main.hh.ast.json
DEBUG_ACID_FILE=adapter_main.hh.acid.json
DEBUG_YML_FILE=adapter_main.hh.acid.yml
$(info -----_gen GEN----)
$(info YML2_FILE $(YML2_FILE))
$(info YSL2_FILE $(YSL2_FILE))
$(info CC_FILE $(PYBIND11_FILE))
.PHONY = all yml pybind
all: pybind
yml: $(YML2_FILE)
pybind: $(YML2_FILE) $(PYBIND11_FILE)
$(YML2_FILE): config.json
pEp_acid_gen $^
$(PYBIND11_FILE) : $(YML2_FILE)
yml2proc --encoding=utf8 -y $(YSL2_FILE) $(YML2_FILE)
clean:
rm -f $(YML2_FILE)
rm -f $(PYBIND11_FILE)
rm -f $(DEBUG_AST_FILE)
rm -f $(DEBUG_ACID_FILE)
rm -f $(DEBUG_YML_FILE)

@ -0,0 +1,98 @@
{
"module_name": "_gen",
"header_filename": "../adapter_main.hh",
"libclang_path": "/opt/local/libexec/llvm-9.0/lib/libclang.dylib",
"variables": [
],
"functions": [
"KEYMANAGEMENT",
"update_identity",
"myself",
"//register_examine_function",
"//do_keymanagement",
"key_mistrusted",
"trust_personal_key",
"trust_own_key",
"key_reset_trust",
"//own_key_is_listed",
"_own_identities_retrieve",
"own_identities_retrieve",
"_own_keys_retrieve",
"own_keys_retrieve",
"set_own_key",
"//clean_own_key_defaults",
"//PEPENGINE",
"update_identity",
"myself",
"//register_examine_function",
"//do_keymanagement",
"key_mistrusted",
"trust_personal_key",
"trust_own_key",
"key_reset_trust",
"//own_key_is_listed",
"own_identities_retrieve",
"//own_keys_retrieve",
"set_own_key",
"//clean_own_key_defaults",
"new_identity",
"//MESSAGE_API",
"encrypt_message",
"encrypt_message_and_add_priv_key",
"encrypt_message_for_self",
"color_from_rating",
"decrypt_message",
"own_message_private_key_details",
"outgoing_message_rating",
"outgoing_message_rating_preview",
"identity_rating",
"get_binary_path",
"get_trustwords",
"get_message_trustwords",
"get_trustwords_for_fprs",
"re_evaluate_message_rating",
"get_key_rating_for_user",
"rating_from_comm_type",
"probe_encrypt",
"//MESSAGE",
"new_message",
"free_message",
"message_dup",
"message_transfer",
"new_message_ref_list",
"free_message_ref_list",
"message_ref_list_dup",
"message_ref_list_add",
"//SYNC_API",
"deliverHandshakeResult",
"//register_sync_callbacks",
"//unregister_sync_callbacks",
"//do_sync_protocol",
"//do_sync_protocol_step",
"//is_sync_thread",
"//new_sync_timeout_event",
"enter_device_group",
"//leave_device_group",
"enable_identity_for_sync",
"disable_identity_for_sync",
"//SYNC_CODEC",
"//decode_Sync_message",
"//encode_Sync_message",
"//PER_to_XER_Sync_msg",
"//XER_to_PER_Sync_msg",
"//DISTRIBUTION_CODEC",
"//decode_Distribution_message",
"//encode_Distribution_message",
"//PER_to_XER_Distribution_msg",
"//XER_to_PER_Distribution_msg"
],
"debug_ast" : 0,
"debug_acid" : 0,
"debug_yml" : 0
}

@ -0,0 +1,22 @@
#include <string>
#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/detail/common.h>
#include "adapter_main.hh"
#include <pEp/Adapter.hh>
#include <pEp/callback_dispatcher.hh>
using namespace std;
namespace alib = pEp::Adapter;
PEP_SESSION pep_session() {
return alib::session();
}
PYBIND11_MODULE(_gen, m) {
// PEP_SESSION
// m.def("pep_session",(PEP_SESSION(*)()) &pep_session);
#include "gen/py_module.pybind11"
}

@ -0,0 +1,32 @@
include ../Makefile.conf
TARGET=$(TARGET_PEP)
# Specific Build settings
CXXFLAGS+=-Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -g -fwrapv -O3 -Wall -pipe -Os -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk
INCLUDES+=
LIB_DIRS+=
LIBS+=-lboost_python38-mt -lboost_locale-mt
LDFLAGS+=
# Combine Settings
CXXFLAGS+=$(INCLUDES)
LDFLAGS+=$(LIB_DIRS)
LDFLAGS+=$(LIBS)
SRCS:=$(wildcard *.cc)
OBJS:=$(SRCS:.cc=.o)
.PHONY: clean
all: $(TARGET)
# Using implicit compile target
# And explicit link taget
$(TARGET): $(OBJS)
$(CXX) $(LDFLAGS) -o $@ $^
clean:
rm -rf $(TARGET)
rm -rf $(OBJS)

@ -0,0 +1,163 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
#include "adapter_main.hh"
#include "message.hh"
#include "message_api.hh"
namespace pEp {
namespace PythonAdapter {
static const char *version_string = "p≡p Python adapter version 0.3";
void init_before_main_module() {
pEpLog("called");
}
// hidden init function, wrapped by hello_world.init()
void _init_after_main_module() {
pEpLog("called");
callback_dispatcher.add(_messageToSend, notifyHandshake, nullptr, nullptr);
Adapter::_messageToSend = CallbackDispatcher::messageToSend;
}
void config_passive_mode(bool enable) {
::config_passive_mode(Adapter::session(), enable);
}
void config_unencrypted_subject(bool enable) {
::config_unencrypted_subject(Adapter::session(), enable);
}
void key_reset_user(const string &user_id, const string &fpr) {
if (user_id == "") {
throw invalid_argument("user_id required");
}
::PEP_STATUS status = ::key_reset_user(Adapter::session(), user_id.c_str(), fpr != "" ? fpr.c_str() : nullptr);
_throw_status(status);
}
void key_reset_user2(const string &user_id) {
key_reset_user(user_id, "");
}
void key_reset_all_own_keys() {
::PEP_STATUS status = ::key_reset_all_own_keys(Adapter::session());
_throw_status(status);
}
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 (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(status_to_string(status));
}
}
::PEP_STATUS _messageToSend(::message *msg) {
pEpLog("called");
try {
PyGILState_STATE gil = PyGILState_Ensure();
pEpLog("GIL Aquired");
bp::object modref = bp::import("pEp");
bp::object funcref = modref.attr("message_to_send");
bp::call<void>(funcref.ptr(), Message());
PyGILState_Release(gil);
pEpLog("GIL released");
} catch (exception &e) {
}
return ::PEP_STATUS_OK;
}
::PEP_STATUS notifyHandshake(::pEp_identity *me, ::pEp_identity *partner, ::sync_handshake_signal signal) {
pEpLog("called");
try {
PyGILState_STATE gil = PyGILState_Ensure();
pEpLog("GIL Aquired");
bp::object modref = bp::import("pEp");
bp::object funcref = modref.attr("notify_handshake");
bp::call<void>(funcref.ptr(), me, partner, signal);
PyGILState_Release(gil);
pEpLog("GIL released");
} catch (exception &e) {
}
return ::PEP_STATUS_OK;
}
void start_sync() {
CallbackDispatcher::start_sync();
}
void shutdown_sync() {
CallbackDispatcher::stop_sync();
}
void debug_color(int ansi_color) {
::set_debug_color(Adapter::session(), ansi_color);
}
void leave_device_group() {
::leave_device_group(Adapter::session());
}
bool is_sync_active() {
return Adapter::is_sync_running();
}
void testfunc() {
_messageToSend(nullptr);
}
void deliverHandshakeResult(int result, bp::object identities) {
identity_list *shared_identities = nullptr;
if (identities != bp::api::object() && boost::python::len(identities)) {
shared_identities = ::new_identity_list(nullptr);
if (!shared_identities) {
throw bad_alloc();
}
try {
::identity_list *si = shared_identities;
for (int i = 0; i < bp::len(identities); ++i) {
Identity ident = bp::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;
}
}
::PEP_STATUS status = ::deliverHandshakeResult(Adapter::session(), (::sync_handshake_result)result, shared_identities);
free_identity_list(shared_identities);
_throw_status(status);
}
} // namespace PythonAdapter
} // namespace pEp

@ -0,0 +1,84 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
#ifndef ADAPTER_MAIN_HH
#define ADAPTER_MAIN_HH
// System
#include <string>
#include <iomanip>
// Boost
#include <boost/python.hpp>
#include <boost/locale.hpp>
// Engine
#include <pEp/pEpEngine.h>
#include <pEp/keymanagement.h>
#include <pEp/identity_list.h>
#include <pEp/key_reset.h>
#include <pEp/sync_api.h>
#include <pEp/mime.h>
#include <pEp/message.h>
#include <pEp/message_api.h>
#include <pEp/sync_codec.h>
#include <pEp/distribution_codec.h>
#include <pEp/timestamp.h>
#include <pEp/stringpair.h>
// libpEpAdapter
#include <pEp/Adapter.hh>
#include <pEp/callback_dispatcher.hh>
#include <pEp/status_to_string.hh>
#include <pEp/pEpLog.hh>
namespace pEp {
namespace PythonAdapter {
using namespace std;
namespace bp = boost::python;
namespace bl = boost::locale;
void init_before_main_module();
void _init_after_main_module();
void testfunc();
//extern string device_name;
string about();
void config_passive_mode(bool enable);
void start_sync();
void shutdown_sync();
void debug_color(int ansi_color);
bool is_sync_active();
void config_unencrypted_subject(bool enable);
void key_reset_user(const string &user_id, const string &fpr);
void key_reset_user2(const string &user_id);
void key_reset_all_own_keys();
void _throw_status(::PEP_STATUS status);
void leave_device_group();
::PEP_STATUS _messageToSend(::message *msg);
::PEP_STATUS notifyHandshake(::pEp_identity *me, ::pEp_identity *partner, ::sync_handshake_signal signal);
void deliverHandshakeResult(int result, bp::object identities);
} // namespace PythonAdapter
} // namespace pEp
#endif // ADAPTER_MAIN_HH

@ -1,161 +1,152 @@
// 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 {
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(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");
if (ident.user_id() == "")
ident.user_id(ident.address());
PEP_STATUS status = myself(Adapter::session(), ident);
_throw_status(status);
}
string _trustwords(Identity me, Identity partner, string lang, bool full) {
if (me.fpr() == "" || partner.fpr() == "")
throw invalid_argument("fingerprint needed in Identities");
if (lang == "" && me.lang() == partner.lang())
lang = me.lang();
char *words = NULL;
size_t size = 0;
PEP_STATUS status = get_trustwords(Adapter::session(), me, partner,
lang.c_str(), &words, &size, full);
_throw_status(status);
return words;
}
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");
PEP_STATUS status = trust_personal_key(Adapter::session(), ident);
_throw_status(status);
}
void set_identity_flags(Identity ident, identity_flags_t flags) {
if (ident.address() == "")
throw invalid_argument("address needed");
if (ident.user_id() == "")
throw invalid_argument("user_id needed");
PEP_STATUS status = set_identity_flags(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");
PEP_STATUS status = unset_identity_flags(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(Adapter::session(), ident);
_throw_status(status);
}
boost::python::list import_key(string key_data) {
::identity_list *private_keys = NULL;
PEP_STATUS status = ::import_key(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));
}
free_identity_list(private_keys);
return result;
}
string export_key(Identity ident) {
PEP_STATUS status = PEP_STATUS_OK;
char *key_data = NULL;
size_t size;
status = ::export_key(Adapter::session(), ident.fpr().c_str(), &key_data, &size);
_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(Adapter::session(), ident.fpr().c_str(), &key_data, &size);
_throw_status(status);
return key_data;
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(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");
}
if (ident.user_id() == "") {
ident.user_id(ident.address());
}
::PEP_STATUS status = ::myself(Adapter::session(), ident);
_throw_status(status);
}
string _trustwords(Identity me, Identity partner, string lang, bool full) {
if (me.fpr() == "" || partner.fpr() == "") {
throw invalid_argument("fingerprint needed in Identities");
}
if (lang == "" && me.lang() == partner.lang()) {
lang = me.lang();
}
char *words = nullptr;
size_t size = 0;
::PEP_STATUS status = ::get_trustwords(Adapter::session(), me, partner, lang.c_str(), &words, &size, full);
_throw_status(status);
return words;
}
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");
}
::PEP_STATUS status = ::trust_personal_key(Adapter::session(), ident);
_throw_status(status);
}
void set_identity_flags(Identity ident,const ::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(Adapter::session(), ident, flags);
_throw_status(status);
}
void unset_identity_flags(Identity ident,const ::identity_flags_t &flags) {
if (ident.address() == "") {
throw invalid_argument("address needed");
}
if (ident.user_id() == "") {
throw invalid_argument("user_id needed");
}
::PEP_STATUS status = ::unset_identity_flags(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(Adapter::session(), ident);
_throw_status(status);
}
bp::list import_key(const string &key_data) {
::identity_list *private_keys = nullptr;
::PEP_STATUS status = ::import_key(Adapter::session(), key_data.c_str(), key_data.size(), &private_keys);
if (status && status != ::PEP_KEY_IMPORTED) {
_throw_status(status);
}
auto result = bp::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();
}
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(Adapter::session(), ident, fpr_c);
_throw_status(status);
}
} // namespace PythonAdapter
result.append(Identity(ident));
}
::free_identity_list(private_keys);
return result;
}
string export_key(Identity ident) {
::PEP_STATUS status = ::PEP_STATUS_OK;
char *key_data = nullptr;
size_t size;
status = ::export_key(Adapter::session(), ident.fpr().c_str(), &key_data, &size);
_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(Adapter::session(), ident.fpr().c_str(), &key_data, &size);
_throw_status(status);
return key_data;
}
void set_own_key(Identity &ident, const 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(Adapter::session(), ident, fpr_c);
_throw_status(status);
}
} // namespace PythonAdapter
} // namespace pEp

@ -4,34 +4,35 @@
#ifndef BASIC_API_HH
#define BASIC_API_HH
#include "pEpmodule.hh"
#include "adapter_main.hh"
#include "identity.hh"
namespace pEp {
namespace PythonAdapter {
namespace PythonAdapter {
void update_identity(Identity &ident);
void update_identity(Identity &ident);
void myself(Identity &ident);
void myself(Identity &ident);
string _trustwords(Identity me, Identity partner, string lang, bool full);
string _trustwords(Identity me, Identity partner, string lang, bool full);
void trust_personal_key(Identity ident);
void trust_personal_key(Identity ident);
void set_identity_flags(Identity ident, identity_flags_t flags);
void set_identity_flags(Identity ident,const ::identity_flags_t &flags);
void unset_identity_flags(Identity ident, identity_flags_t flags);
void unset_identity_flags(Identity ident,const ::identity_flags_t &flags);
void key_reset_trust(Identity ident);
void key_reset_trust(Identity ident);
boost::python::list import_key(string key_data);
bp::list import_key(const string &key_data);
string export_key(Identity ident);
string export_key(Identity ident);
string export_secret_key(Identity ident);
string export_secret_key(Identity ident);
void set_own_key(Identity &ident, string fpr);
void set_own_key(Identity &ident, const string &fpr);
} /* namespace PythonAdapter */
} /* namespace PythonAdapter */
} /* namespace pEp */
#endif /* BASIC_API_HH */
#endif /* BASIC_API_HH */

@ -1,170 +1,166 @@
// 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 {
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(pEp_identity *ident)
: _ident(ident, &::free_identity) {
}
Identity::~Identity() {
}
Identity::operator pEp_identity *() {
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::_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");
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);
}
string Identity::lang() {
return _ident->lang;
}
int Identity::rating() {
if (!(_ident->address))
throw invalid_argument("address must be given");
PEP_rating rating = PEP_rating_undefined;
PEP_STATUS status = ::identity_rating(Adapter::session(), _ident.get(), &rating);
_throw_status(status);
return (int) rating;
}
PEP_color Identity::color() {
return _color(rating());
}
Identity Identity::copy() {
pEp_identity *dup = ::identity_dup(*this);
if (!dup)
throw bad_alloc();
return Identity(dup);
}
Identity Identity::deepcopy(dict &) {
return copy();
}
void Identity::update() {
update_identity(*this);
}
void Identity::key_reset(string fpr) {
PEP_STATUS status = ::key_reset_identity(Adapter::session(), *this,
fpr != "" ? fpr.c_str() : nullptr);
_throw_status(status);
}
void Identity::key_mistrusted() {
PEP_STATUS status = ::key_mistrusted(Adapter::session(), *this);
_throw_status(status);
}
bool Identity::is_pEp_user() {
bool result;
PEP_STATUS status = ::is_pEp_user(Adapter::session(), *this, &result);
_throw_status(status);
return result;
}
void Identity::enable_for_sync() {
PEP_STATUS status = ::enable_identity_for_sync(Adapter::session(), *this);
_throw_status(status);
}
void Identity::disable_for_sync() {
PEP_STATUS status = ::disable_identity_for_sync(Adapter::session(), *this);
_throw_status(status);
}
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);
}