From 7601a8ec2a5edcf8c3950a68e7056dad3bd08a9b Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Fri, 26 Jun 2020 22:25:06 +0200 Subject: [PATCH] convenience functions --- passphrase_cache.hh | 24 ++++++++++++++++++++---- passphrase_cache.hxx | 20 ++++++++++++++++++++ test/test_passphrase_cache.cc | 29 +++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 passphrase_cache.hxx diff --git a/passphrase_cache.hh b/passphrase_cache.hh index d44d02b..248cd67 100644 --- a/passphrase_cache.hh +++ b/passphrase_cache.hh @@ -5,6 +5,7 @@ #include #include #include +#include namespace pEp { class PassphraseCache { @@ -28,25 +29,40 @@ namespace pEp { duration _timeout; public: - PassphraseCache(int max_size=20, duration timeout = std::chrono::minutes(10)) : - _max_size(max_size), _timeout(timeout) { } + PassphraseCache(int max_size=20, duration timeout = + std::chrono::minutes(10)) : _max_size(max_size), + _timeout(timeout) { } ~PassphraseCache() { } - PassphraseCache(const PassphraseCache& second) : - _cache(second._cache), _max_size(second._max_size), _timeout(second._timeout) { } + PassphraseCache(const PassphraseCache& second) : _cache(second._cache), + _max_size(second._max_size), _timeout(second._timeout) { } // adding a passphrase to the cache, which will timeout + void add(std::string passphrase); // for each passphrase call the callee until it returns true for a // matching passphrase or no passphrases are left // always tests empty passphrase first // returns true if a passphrase was matching, false otherwise + using passphrase_callee = std::function; bool for_each_passphrase(const passphrase_callee& callee); + // convenience functions + // i.e. + // status = cache.api(::encrypt_message, session, src, extra, dst, enc_format, flags) + // will call + // status = ::encrypt_message(session, src, extra, dst, enc_format, flags) + // using for_each_passphrase() + + template PEP_STATUS api(PEP_STATUS f(PEP_SESSION, A...), + PEP_SESSION session, A... a); + protected: void cleanup(); void refresh(cache::iterator entry); }; }; +#include "passphrase_cache.hxx" + diff --git a/passphrase_cache.hxx b/passphrase_cache.hxx new file mode 100644 index 0000000..3214f05 --- /dev/null +++ b/passphrase_cache.hxx @@ -0,0 +1,20 @@ +#pragma once +#include "passphrase_cache.hh" + +namespace pEp { + template PEP_STATUS PassphraseCache::api( + PEP_STATUS f(PEP_SESSION, A...), PEP_SESSION session, A... a) + { + PEP_STATUS status; + + for_each_passphrase([&](std::string passphrase) { + ::config_passphrase(session, passphrase.c_str()); + status = f(session, a...); + return status != PEP_PASSPHRASE_REQUIRED && + status != PEP_WRONG_PASSPHRASE; + }); + + return status; + } +}; + diff --git a/test/test_passphrase_cache.cc b/test/test_passphrase_cache.cc index 16ca78f..bbc2724 100644 --- a/test/test_passphrase_cache.cc +++ b/test/test_passphrase_cache.cc @@ -4,8 +4,30 @@ #include "passphrase_cache.hh" +extern "C" { + PEP_STATUS api_test1(PEP_SESSION session, const char *str, char *bytes, int n, ::stringlist_t *sl) + { + std::cout << "called api_test1\n"; + return PEP_WRONG_PASSPHRASE; + } + + PEP_STATUS api_test2(PEP_SESSION session, const char *str, char *bytes, int n, ::stringlist_t *sl) + { + std::cout << "called api_test2\n"; + return PEP_STATUS_OK; + } +}; + int main() { + PEP_SESSION session; + PEP_STATUS status = ::init(&session, NULL, NULL); + + const char *str = "23"; + char *bytes = NULL; + int n = 42; + ::stringlist_t *sl = NULL; + pEp::PassphraseCache cache{2, std::chrono::seconds(1)}; cache.add("say"); cache.add("hello"); @@ -20,11 +42,18 @@ int main() std::cout << "expected: two passphrases but reverse order\n"; cache.for_each_passphrase([&](std::string passphrase){std::cout << "'" << passphrase << "'\n"; return false;}); + cache.api(api_test1, session, str, bytes, n, sl); + cache.api(api_test2, session, str, bytes, n, sl); + sleep(2); std::cout << "expected: no passphrase\n"; cache.for_each_passphrase([&](std::string passphrase){std::cout << "'" << passphrase << "'\n"; return false;}); + cache.api(api_test1, session, str, bytes, n, sl); + cache.api(api_test2, session, str, bytes, n, sl); + + ::release(session); return 0; }