mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-28 23:55:52 +00:00
@@ -111,6 +111,7 @@ if(BUILD_TESTS)
|
||||
unittests/Logger.cpp
|
||||
unittests/Config.cpp
|
||||
unittests/ProfilerTest.cpp
|
||||
unittests/JsonUtilTest.cpp
|
||||
unittests/DOSGuard.cpp
|
||||
unittests/SubscriptionTest.cpp
|
||||
unittests/SubscriptionManagerTest.cpp
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <webserver/Context.h>
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <util/JsonUtils.h>
|
||||
|
||||
namespace RPC {
|
||||
|
||||
@@ -231,8 +232,10 @@ logDuration(Web::Context const& ctx, T const& dur)
|
||||
static clio::Logger log{"RPC"};
|
||||
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 msg =
|
||||
fmt::format("Request processing duration = {} milliseconds. request = {}", millis, serialize(ctx.params));
|
||||
auto const msg = fmt::format(
|
||||
"Request processing duration = {} milliseconds. request = {}",
|
||||
millis,
|
||||
serialize(util::removeSecret(ctx.params)));
|
||||
|
||||
if (seconds > 10)
|
||||
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/RPCHelpers.h>
|
||||
#include <rpc/common/impl/APIVersionParser.h>
|
||||
#include <util/JsonUtils.h>
|
||||
#include <util/Profiler.h>
|
||||
|
||||
#include <boost/json/parse.hpp>
|
||||
@@ -125,7 +126,8 @@ private:
|
||||
std::shared_ptr<Server::ConnectionBase> connection)
|
||||
{
|
||||
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;
|
||||
|
||||
|
||||
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