mirror of
https://github.com/XRPLF/clio.git
synced 2025-12-03 10:05:51 +00:00
@@ -111,6 +111,7 @@ if(BUILD_TESTS)
|
|||||||
unittests/Logger.cpp
|
unittests/Logger.cpp
|
||||||
unittests/Config.cpp
|
unittests/Config.cpp
|
||||||
unittests/ProfilerTest.cpp
|
unittests/ProfilerTest.cpp
|
||||||
|
unittests/JsonUtilTest.cpp
|
||||||
unittests/DOSGuard.cpp
|
unittests/DOSGuard.cpp
|
||||||
unittests/SubscriptionTest.cpp
|
unittests/SubscriptionTest.cpp
|
||||||
unittests/SubscriptionManagerTest.cpp
|
unittests/SubscriptionManagerTest.cpp
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <webserver/Context.h>
|
#include <webserver/Context.h>
|
||||||
|
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
|
#include <util/JsonUtils.h>
|
||||||
|
|
||||||
namespace RPC {
|
namespace RPC {
|
||||||
|
|
||||||
@@ -231,8 +232,10 @@ logDuration(Web::Context const& ctx, T const& dur)
|
|||||||
static clio::Logger log{"RPC"};
|
static clio::Logger log{"RPC"};
|
||||||
auto const millis = std::chrono::duration_cast<std::chrono::milliseconds>(dur).count();
|
auto const millis = std::chrono::duration_cast<std::chrono::milliseconds>(dur).count();
|
||||||
auto const seconds = std::chrono::duration_cast<std::chrono::seconds>(dur).count();
|
auto const seconds = std::chrono::duration_cast<std::chrono::seconds>(dur).count();
|
||||||
auto const msg =
|
auto const msg = fmt::format(
|
||||||
fmt::format("Request processing duration = {} milliseconds. request = {}", millis, serialize(ctx.params));
|
"Request processing duration = {} milliseconds. request = {}",
|
||||||
|
millis,
|
||||||
|
serialize(util::removeSecret(ctx.params)));
|
||||||
|
|
||||||
if (seconds > 10)
|
if (seconds > 10)
|
||||||
log.error() << ctx.tag() << msg;
|
log.error() << ctx.tag() << msg;
|
||||||
|
|||||||
53
src/util/JsonUtils.h
Normal file
53
src/util/JsonUtils.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of clio: https://github.com/XRPLF/clio
|
||||||
|
Copyright (c) 2023, the clio developers.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <boost/json.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace util {
|
||||||
|
|
||||||
|
inline boost::json::object
|
||||||
|
removeSecret(boost::json::object const& object)
|
||||||
|
{
|
||||||
|
auto newObject = object;
|
||||||
|
auto const secretFields = {"secret", "seed", "seed_hex", "passphrase"};
|
||||||
|
|
||||||
|
if (newObject.contains("params") and newObject.at("params").is_array() and
|
||||||
|
not newObject.at("params").as_array().empty() and newObject.at("params").as_array()[0].is_object())
|
||||||
|
{
|
||||||
|
for (auto const& secretField : secretFields)
|
||||||
|
{
|
||||||
|
if (newObject.at("params").as_array()[0].as_object().contains(secretField))
|
||||||
|
newObject.at("params").as_array()[0].as_object()[secretField] = "*";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// for websocket requests
|
||||||
|
for (auto const& secretField : secretFields)
|
||||||
|
{
|
||||||
|
if (newObject.contains(secretField))
|
||||||
|
newObject[secretField] = "*";
|
||||||
|
}
|
||||||
|
|
||||||
|
return newObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace util
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <rpc/Factories.h>
|
#include <rpc/Factories.h>
|
||||||
#include <rpc/RPCHelpers.h>
|
#include <rpc/RPCHelpers.h>
|
||||||
#include <rpc/common/impl/APIVersionParser.h>
|
#include <rpc/common/impl/APIVersionParser.h>
|
||||||
|
#include <util/JsonUtils.h>
|
||||||
#include <util/Profiler.h>
|
#include <util/Profiler.h>
|
||||||
|
|
||||||
#include <boost/json/parse.hpp>
|
#include <boost/json/parse.hpp>
|
||||||
@@ -125,7 +126,8 @@ private:
|
|||||||
std::shared_ptr<Server::ConnectionBase> connection)
|
std::shared_ptr<Server::ConnectionBase> connection)
|
||||||
{
|
{
|
||||||
log_.info() << connection->tag() << (connection->upgraded ? "ws" : "http")
|
log_.info() << connection->tag() << (connection->upgraded ? "ws" : "http")
|
||||||
<< " received request from work queue: " << request << " ip = " << connection->clientIp;
|
<< " received request from work queue: " << util::removeSecret(request)
|
||||||
|
<< " ip = " << connection->clientIp;
|
||||||
|
|
||||||
auto const id = request.contains("id") ? request.at("id") : nullptr;
|
auto const id = request.contains("id") ? request.at("id") : nullptr;
|
||||||
|
|
||||||
|
|||||||
62
unittests/JsonUtilTest.cpp
Normal file
62
unittests/JsonUtilTest.cpp
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of clio: https://github.com/XRPLF/clio
|
||||||
|
Copyright (c) 2023, the clio developers.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include <util/JsonUtils.h>
|
||||||
|
|
||||||
|
#include <boost/json.hpp>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
TEST(JsonUtils, RemoveSecrets)
|
||||||
|
{
|
||||||
|
auto json = boost::json::parse(R"({
|
||||||
|
"secret": "snoopy",
|
||||||
|
"seed": "woodstock",
|
||||||
|
"seed_hex": "charlie",
|
||||||
|
"passphrase": "lucy"
|
||||||
|
})")
|
||||||
|
.as_object();
|
||||||
|
|
||||||
|
auto json2 = util::removeSecret(json);
|
||||||
|
EXPECT_EQ(json2.at("secret").as_string(), "*");
|
||||||
|
EXPECT_EQ(json2.at("seed").as_string(), "*");
|
||||||
|
EXPECT_EQ(json2.at("seed_hex").as_string(), "*");
|
||||||
|
EXPECT_EQ(json2.at("passphrase").as_string(), "*");
|
||||||
|
|
||||||
|
json = boost::json::parse(R"({
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"secret": "snoopy",
|
||||||
|
"seed": "woodstock",
|
||||||
|
"seed_hex": "charlie",
|
||||||
|
"passphrase": "lucy"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})")
|
||||||
|
.as_object();
|
||||||
|
|
||||||
|
json2 = util::removeSecret(json);
|
||||||
|
EXPECT_TRUE(json2.contains("params"));
|
||||||
|
EXPECT_TRUE(json2.at("params").is_array());
|
||||||
|
EXPECT_TRUE(json2.at("params").as_array().size() > 0);
|
||||||
|
json2 = json2.at("params").as_array()[0].as_object();
|
||||||
|
EXPECT_EQ(json2.at("secret").as_string(), "*");
|
||||||
|
EXPECT_EQ(json2.at("seed").as_string(), "*");
|
||||||
|
EXPECT_EQ(json2.at("seed_hex").as_string(), "*");
|
||||||
|
EXPECT_EQ(json2.at("passphrase").as_string(), "*");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user