From b6edab71714cf643381ea506a6a6967c2b92e8c9 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Wed, 14 Jun 2017 20:19:18 +0100 Subject: [PATCH] Implement self-destruct upon read when selfdes=1 in POST --- lib/incredis | 2 +- src/kamokan_impl/storage.cpp | 16 ++++++++++++++-- src/kamokan_impl/storage.hpp | 1 + src/kamokan_impl/submit_paste_response.cpp | 11 ++++++++--- src/kamokan_impl/submit_paste_response.hpp | 7 ++++++- test/simulation/fake_storage.cpp | 2 ++ test/simulation/fake_storage.hpp | 12 +++++++----- 7 files changed, 39 insertions(+), 12 deletions(-) diff --git a/lib/incredis b/lib/incredis index 045675c..b92d0f3 160000 --- a/lib/incredis +++ b/lib/incredis @@ -1 +1 @@ -Subproject commit 045675c8084fce265330686ab29dc6009b84e341 +Subproject commit b92d0f38e5092579f56d1b8f3b709226468da261 diff --git a/src/kamokan_impl/storage.cpp b/src/kamokan_impl/storage.cpp index 554a839..e47706c 100644 --- a/src/kamokan_impl/storage.cpp +++ b/src/kamokan_impl/storage.cpp @@ -22,6 +22,7 @@ #include "duckhandy/stringize.h" #include "spdlog.hpp" #include "truncated_string.hpp" +#include "string_conv.hpp" #include #include #include @@ -94,6 +95,7 @@ namespace kamokan { const boost::string_view& parText, uint32_t parExpiry, const boost::string_view& parLang, + bool parSelfDestruct, const std::string& parRemoteIP ) const { using tawashi::ErrorReasons; @@ -123,7 +125,8 @@ namespace kamokan { if (redis.hmset(token, "pastie", parText, "max_ttl", dhandy::lexical_cast(parExpiry), - "lang", parLang) + "lang", parLang, + "selfdes", (parSelfDestruct ? "1" : "0")) ) { redis.set(parRemoteIP, ""); redis.expire(parRemoteIP, m_settings->as("resubmit_wait")); @@ -138,8 +141,17 @@ namespace kamokan { using opt_string = redis::IncRedis::opt_string; using opt_string_list = redis::IncRedis::opt_string_list; - opt_string_list pastie_reply = m_redis->hmget(parToken, "pastie"); + opt_string_list pastie_reply = m_redis->hmget(parToken, "pastie", "selfdes"); opt_string pastie = (pastie_reply and not pastie_reply->empty() ? (*pastie_reply)[0] : opt_string()); + opt_string selfdes = (pastie_reply and not pastie_reply->size() > 1 ? (*pastie_reply)[1] : opt_string()); + + if (selfdes and string_conv(*selfdes)) { + const bool deleted = m_redis->del(parToken); + if (not deleted) { + auto statuslog = spdlog::get("statuslog"); + statuslog->error("Pastie \"{}\" was marked as self-destructing but DEL failed to delete it", parToken); + } + } #if defined(SPDLOG_DEBUG_ON) { diff --git a/src/kamokan_impl/storage.hpp b/src/kamokan_impl/storage.hpp index 8ab410d..a7ceea8 100644 --- a/src/kamokan_impl/storage.hpp +++ b/src/kamokan_impl/storage.hpp @@ -49,6 +49,7 @@ namespace kamokan { const boost::string_view& parText, uint32_t parExpiry, const boost::string_view& parLang, + bool parSelfDestruct, const std::string& parRemoteIP ) const; diff --git a/src/kamokan_impl/submit_paste_response.cpp b/src/kamokan_impl/submit_paste_response.cpp index 1f03fec..8bbb063 100644 --- a/src/kamokan_impl/submit_paste_response.cpp +++ b/src/kamokan_impl/submit_paste_response.cpp @@ -23,6 +23,7 @@ #include "duckhandy/lexical_cast.hpp" #include "tawashi_exception.hpp" #include "ip_utils.hpp" +#include "string_conv.hpp" #include #include #include @@ -34,6 +35,7 @@ namespace kamokan { const char g_post_key[] = "pastie"; const char g_language_key[] = "lang"; const char g_duration_key[] = "ttl"; + const char g_self_destruct[] = "selfdes"; class MissingPostVarError : public tawashi::Exception { public: @@ -100,6 +102,7 @@ namespace kamokan { boost::string_view pastie; boost::string_view lang; boost::string_view duration; + bool self_destruct; auto statuslog = spdlog::get("statuslog"); assert(statuslog); @@ -110,6 +113,7 @@ namespace kamokan { pastie = get_value_from_post(post, make_string_view(g_post_key)); lang = get_value_from_post_log_failure(post, make_string_view(g_language_key)); duration = get_value_from_post_log_failure(post, make_string_view(g_duration_key)); + self_destruct = string_conv(get_value_from_post_log_failure(post, make_string_view(g_self_destruct))); } catch (const tawashi::UnsupportedContentTypeException& err) { statuslog->info( @@ -139,7 +143,7 @@ namespace kamokan { //TODO: replace boost's lexical_cast with mine when I have some checks //over invalid inputs const uint32_t duration_int = std::max(std::min((duration.empty() ? 86400U : boost::lexical_cast(duration)), 2628000U), 1U); - StringOrHeader submit_result = submit_to_storage(pastie, duration_int, lang); + StringOrHeader submit_result = submit_to_storage(pastie, duration_int, lang, self_destruct); const auto& token = submit_result.first; if (token) { @@ -162,11 +166,12 @@ namespace kamokan { auto SubmitPasteResponse::submit_to_storage ( const boost::string_view& parText, uint32_t parExpiry, - const boost::string_view& parLang + const boost::string_view& parLang, + bool parSelfDestruct ) -> StringOrHeader { auto& storage = this->storage(); std::string remote_ip = tawashi::guess_real_remote_ip(cgi_env()); - Storage::SubmissionResult submission_res = storage.submit_pastie(parText, parExpiry, parLang, remote_ip); + Storage::SubmissionResult submission_res = storage.submit_pastie(parText, parExpiry, parLang, parSelfDestruct, remote_ip); if (not submission_res.error) return std::make_pair(boost::make_optional(std::move(submission_res.token)), tawashi::HttpHeader()); else diff --git a/src/kamokan_impl/submit_paste_response.hpp b/src/kamokan_impl/submit_paste_response.hpp index 868ad7f..d8a8768 100644 --- a/src/kamokan_impl/submit_paste_response.hpp +++ b/src/kamokan_impl/submit_paste_response.hpp @@ -50,6 +50,11 @@ namespace kamokan { typedef std::pair, tawashi::HttpHeader> StringOrHeader; virtual tawashi::HttpHeader on_process() override; - StringOrHeader submit_to_storage (const boost::string_view& parText, uint32_t parExpiry, const boost::string_view& parLang); + StringOrHeader submit_to_storage ( + const boost::string_view& parText, + uint32_t parExpiry, + const boost::string_view& parLang, + bool parSelfDestruct + ); }; } //namespace kamokan diff --git a/test/simulation/fake_storage.cpp b/test/simulation/fake_storage.cpp index ab4001b..6013599 100644 --- a/test/simulation/fake_storage.cpp +++ b/test/simulation/fake_storage.cpp @@ -44,6 +44,7 @@ namespace kamokan { const boost::string_view& parText, uint32_t parExpiry, const boost::string_view& parLang, + bool parSelfDestruct, const std::string& parRemoteIP ) const { SubmittedPastie pastie; @@ -53,6 +54,7 @@ namespace kamokan { pastie.lang = std::string(parLang); pastie.remote_ip = parRemoteIP; pastie.token = token; + pastie.self_destruct = parSelfDestruct; m_submitted_pasties.push_back(std::move(pastie)); Storage::SubmissionResult submission_res; diff --git a/test/simulation/fake_storage.hpp b/test/simulation/fake_storage.hpp index 2297bd8..ac02f9e 100644 --- a/test/simulation/fake_storage.hpp +++ b/test/simulation/fake_storage.hpp @@ -35,22 +35,24 @@ namespace kamokan { std::string remote_ip; std::string token; uint32_t expiry; + bool self_destruct; }; FakeStorage (const Kakoune::SafePtr& parSettings, bool parItsConnected); kamokan_virtual_testing ~FakeStorage(); - kamokan_virtual_testing void connect_async(); - kamokan_virtual_testing bool is_connected() const; - kamokan_virtual_testing void finalize_connection(); + kamokan_virtual_testing void connect_async() override; + kamokan_virtual_testing bool is_connected() const override; + kamokan_virtual_testing void finalize_connection() override; kamokan_virtual_testing SubmissionResult submit_pastie ( const boost::string_view& parText, uint32_t parExpiry, const boost::string_view& parLang, + bool parSelfDestruct, const std::string& parRemoteIP - ) const; + ) const override; - kamokan_virtual_testing boost::optional retrieve_pastie (const boost::string_view& parToken) const; + kamokan_virtual_testing boost::optional retrieve_pastie (const boost::string_view& parToken) const override; const std::vector& submitted_pasties() const;