mirror of
https://github.com/KingDuckZ/kamokan.git
synced 2024-12-01 00:45:41 +00:00
Implement self-destruct upon read when selfdes=1 in POST
This commit is contained in:
parent
8d19c794ed
commit
b6edab7171
7 changed files with 39 additions and 12 deletions
|
@ -1 +1 @@
|
||||||
Subproject commit 045675c8084fce265330686ab29dc6009b84e341
|
Subproject commit b92d0f38e5092579f56d1b8f3b709226468da261
|
|
@ -22,6 +22,7 @@
|
||||||
#include "duckhandy/stringize.h"
|
#include "duckhandy/stringize.h"
|
||||||
#include "spdlog.hpp"
|
#include "spdlog.hpp"
|
||||||
#include "truncated_string.hpp"
|
#include "truncated_string.hpp"
|
||||||
|
#include "string_conv.hpp"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -94,6 +95,7 @@ namespace kamokan {
|
||||||
const boost::string_view& parText,
|
const boost::string_view& parText,
|
||||||
uint32_t parExpiry,
|
uint32_t parExpiry,
|
||||||
const boost::string_view& parLang,
|
const boost::string_view& parLang,
|
||||||
|
bool parSelfDestruct,
|
||||||
const std::string& parRemoteIP
|
const std::string& parRemoteIP
|
||||||
) const {
|
) const {
|
||||||
using tawashi::ErrorReasons;
|
using tawashi::ErrorReasons;
|
||||||
|
@ -123,7 +125,8 @@ namespace kamokan {
|
||||||
if (redis.hmset(token,
|
if (redis.hmset(token,
|
||||||
"pastie", parText,
|
"pastie", parText,
|
||||||
"max_ttl", dhandy::lexical_cast<std::string>(parExpiry),
|
"max_ttl", dhandy::lexical_cast<std::string>(parExpiry),
|
||||||
"lang", parLang)
|
"lang", parLang,
|
||||||
|
"selfdes", (parSelfDestruct ? "1" : "0"))
|
||||||
) {
|
) {
|
||||||
redis.set(parRemoteIP, "");
|
redis.set(parRemoteIP, "");
|
||||||
redis.expire(parRemoteIP, m_settings->as<uint32_t>("resubmit_wait"));
|
redis.expire(parRemoteIP, m_settings->as<uint32_t>("resubmit_wait"));
|
||||||
|
@ -138,8 +141,17 @@ namespace kamokan {
|
||||||
using opt_string = redis::IncRedis::opt_string;
|
using opt_string = redis::IncRedis::opt_string;
|
||||||
using opt_string_list = redis::IncRedis::opt_string_list;
|
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 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<bool>(*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)
|
#if defined(SPDLOG_DEBUG_ON)
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,6 +49,7 @@ namespace kamokan {
|
||||||
const boost::string_view& parText,
|
const boost::string_view& parText,
|
||||||
uint32_t parExpiry,
|
uint32_t parExpiry,
|
||||||
const boost::string_view& parLang,
|
const boost::string_view& parLang,
|
||||||
|
bool parSelfDestruct,
|
||||||
const std::string& parRemoteIP
|
const std::string& parRemoteIP
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "duckhandy/lexical_cast.hpp"
|
#include "duckhandy/lexical_cast.hpp"
|
||||||
#include "tawashi_exception.hpp"
|
#include "tawashi_exception.hpp"
|
||||||
#include "ip_utils.hpp"
|
#include "ip_utils.hpp"
|
||||||
|
#include "string_conv.hpp"
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
@ -34,6 +35,7 @@ namespace kamokan {
|
||||||
const char g_post_key[] = "pastie";
|
const char g_post_key[] = "pastie";
|
||||||
const char g_language_key[] = "lang";
|
const char g_language_key[] = "lang";
|
||||||
const char g_duration_key[] = "ttl";
|
const char g_duration_key[] = "ttl";
|
||||||
|
const char g_self_destruct[] = "selfdes";
|
||||||
|
|
||||||
class MissingPostVarError : public tawashi::Exception {
|
class MissingPostVarError : public tawashi::Exception {
|
||||||
public:
|
public:
|
||||||
|
@ -100,6 +102,7 @@ namespace kamokan {
|
||||||
boost::string_view pastie;
|
boost::string_view pastie;
|
||||||
boost::string_view lang;
|
boost::string_view lang;
|
||||||
boost::string_view duration;
|
boost::string_view duration;
|
||||||
|
bool self_destruct;
|
||||||
|
|
||||||
auto statuslog = spdlog::get("statuslog");
|
auto statuslog = spdlog::get("statuslog");
|
||||||
assert(statuslog);
|
assert(statuslog);
|
||||||
|
@ -110,6 +113,7 @@ namespace kamokan {
|
||||||
pastie = get_value_from_post(post, make_string_view(g_post_key));
|
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));
|
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));
|
duration = get_value_from_post_log_failure(post, make_string_view(g_duration_key));
|
||||||
|
self_destruct = string_conv<bool>(get_value_from_post_log_failure(post, make_string_view(g_self_destruct)));
|
||||||
}
|
}
|
||||||
catch (const tawashi::UnsupportedContentTypeException& err) {
|
catch (const tawashi::UnsupportedContentTypeException& err) {
|
||||||
statuslog->info(
|
statuslog->info(
|
||||||
|
@ -139,7 +143,7 @@ namespace kamokan {
|
||||||
//TODO: replace boost's lexical_cast with mine when I have some checks
|
//TODO: replace boost's lexical_cast with mine when I have some checks
|
||||||
//over invalid inputs
|
//over invalid inputs
|
||||||
const uint32_t duration_int = std::max(std::min((duration.empty() ? 86400U : boost::lexical_cast<uint32_t>(duration)), 2628000U), 1U);
|
const uint32_t duration_int = std::max(std::min((duration.empty() ? 86400U : boost::lexical_cast<uint32_t>(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;
|
const auto& token = submit_result.first;
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
|
@ -162,11 +166,12 @@ namespace kamokan {
|
||||||
auto SubmitPasteResponse::submit_to_storage (
|
auto SubmitPasteResponse::submit_to_storage (
|
||||||
const boost::string_view& parText,
|
const boost::string_view& parText,
|
||||||
uint32_t parExpiry,
|
uint32_t parExpiry,
|
||||||
const boost::string_view& parLang
|
const boost::string_view& parLang,
|
||||||
|
bool parSelfDestruct
|
||||||
) -> StringOrHeader {
|
) -> StringOrHeader {
|
||||||
auto& storage = this->storage();
|
auto& storage = this->storage();
|
||||||
std::string remote_ip = tawashi::guess_real_remote_ip(cgi_env());
|
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)
|
if (not submission_res.error)
|
||||||
return std::make_pair(boost::make_optional(std::move(submission_res.token)), tawashi::HttpHeader());
|
return std::make_pair(boost::make_optional(std::move(submission_res.token)), tawashi::HttpHeader());
|
||||||
else
|
else
|
||||||
|
|
|
@ -50,6 +50,11 @@ namespace kamokan {
|
||||||
typedef std::pair<boost::optional<std::string>, tawashi::HttpHeader> StringOrHeader;
|
typedef std::pair<boost::optional<std::string>, tawashi::HttpHeader> StringOrHeader;
|
||||||
|
|
||||||
virtual tawashi::HttpHeader on_process() override;
|
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
|
} //namespace kamokan
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace kamokan {
|
||||||
const boost::string_view& parText,
|
const boost::string_view& parText,
|
||||||
uint32_t parExpiry,
|
uint32_t parExpiry,
|
||||||
const boost::string_view& parLang,
|
const boost::string_view& parLang,
|
||||||
|
bool parSelfDestruct,
|
||||||
const std::string& parRemoteIP
|
const std::string& parRemoteIP
|
||||||
) const {
|
) const {
|
||||||
SubmittedPastie pastie;
|
SubmittedPastie pastie;
|
||||||
|
@ -53,6 +54,7 @@ namespace kamokan {
|
||||||
pastie.lang = std::string(parLang);
|
pastie.lang = std::string(parLang);
|
||||||
pastie.remote_ip = parRemoteIP;
|
pastie.remote_ip = parRemoteIP;
|
||||||
pastie.token = token;
|
pastie.token = token;
|
||||||
|
pastie.self_destruct = parSelfDestruct;
|
||||||
m_submitted_pasties.push_back(std::move(pastie));
|
m_submitted_pasties.push_back(std::move(pastie));
|
||||||
|
|
||||||
Storage::SubmissionResult submission_res;
|
Storage::SubmissionResult submission_res;
|
||||||
|
|
|
@ -35,22 +35,24 @@ namespace kamokan {
|
||||||
std::string remote_ip;
|
std::string remote_ip;
|
||||||
std::string token;
|
std::string token;
|
||||||
uint32_t expiry;
|
uint32_t expiry;
|
||||||
|
bool self_destruct;
|
||||||
};
|
};
|
||||||
|
|
||||||
FakeStorage (const Kakoune::SafePtr<SettingsBag>& parSettings, bool parItsConnected);
|
FakeStorage (const Kakoune::SafePtr<SettingsBag>& parSettings, bool parItsConnected);
|
||||||
kamokan_virtual_testing ~FakeStorage();
|
kamokan_virtual_testing ~FakeStorage();
|
||||||
|
|
||||||
kamokan_virtual_testing void connect_async();
|
kamokan_virtual_testing void connect_async() override;
|
||||||
kamokan_virtual_testing bool is_connected() const;
|
kamokan_virtual_testing bool is_connected() const override;
|
||||||
kamokan_virtual_testing void finalize_connection();
|
kamokan_virtual_testing void finalize_connection() override;
|
||||||
kamokan_virtual_testing SubmissionResult submit_pastie (
|
kamokan_virtual_testing SubmissionResult submit_pastie (
|
||||||
const boost::string_view& parText,
|
const boost::string_view& parText,
|
||||||
uint32_t parExpiry,
|
uint32_t parExpiry,
|
||||||
const boost::string_view& parLang,
|
const boost::string_view& parLang,
|
||||||
|
bool parSelfDestruct,
|
||||||
const std::string& parRemoteIP
|
const std::string& parRemoteIP
|
||||||
) const;
|
) const override;
|
||||||
|
|
||||||
kamokan_virtual_testing boost::optional<std::string> retrieve_pastie (const boost::string_view& parToken) const;
|
kamokan_virtual_testing boost::optional<std::string> retrieve_pastie (const boost::string_view& parToken) const override;
|
||||||
|
|
||||||
const std::vector<SubmittedPastie>& submitted_pasties() const;
|
const std::vector<SubmittedPastie>& submitted_pasties() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue