online.git: common/Authorization.hpp test/RequestDetailsTests.cpp wsd/ClientSession.cpp

0 views
Skip to first unread message

"Ashod Nakashian (via cogerrit)"

unread,
5:24 AM (1 hour ago) 5:24 AM
to collaboraon...@googlegroups.com
common/Authorization.hpp | 18 ++++++++++
test/RequestDetailsTests.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++
wsd/ClientSession.cpp | 7 ++-
3 files changed, 100 insertions(+), 2 deletions(-)

New commits:
commit c015fcc3db92ea2d0d32d8d2ea21e8065ea12509
Author: Ashod Nakashian <ashod.n...@collabora.co.uk>
AuthorDate: Mon Apr 20 19:32:28 2026 -0400
Commit: Ashod Nakashian <ashod.n...@collabora.co.uk>
CommitDate: Wed Apr 29 09:23:48 2026 +0000

wsd: dump state for Authorization

Change-Id: Ibedbf4126bdb45422a99c94b9bb52e557bd4b6ee
Signed-off-by: Ashod Nakashian <ashod.n...@collabora.co.uk>
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1709
Tested-by: Jenkins CPCI <rel...@collaboraoffice.com>
Tested-by: Caolán McNamara <caolan....@collabora.com>
Reviewed-by: Caolán McNamara <caolan....@collabora.com>

diff --git a/common/Authorization.hpp b/common/Authorization.hpp
index 386b977b617d..9a828d284bd5 100644
--- a/common/Authorization.hpp
+++ b/common/Authorization.hpp
@@ -13,6 +13,7 @@

#pragma once

+#include <common/Anonymizer.hpp>
#include <common/Log.hpp>
#include <common/StateEnum.hpp>

@@ -132,6 +133,23 @@ public:

/// Set the Authorization: header in request.
void authorizeRequest(Poco::Net::HTTPRequest& request) const;
+
+ void dumpState(std::ostream& os, const std::string& indent = "\n ") const
+ {
+ const auto now = std::chrono::system_clock::now();
+
+ os << indent << "Authorization: " << (Anonymizer::enabled() ? "<redacted>" : _data);
+ os << indent << "\ttype: " << name(_type);
+ os << indent << "\texpiryEpoch (TTL): " << _expiryEpoch
+ << Util::getTimeForLog(
+ now, std::chrono::system_clock::time_point(
+ std::chrono::duration_cast<std::chrono::system_clock::duration>(
+ _expiryEpoch)));
+ os << indent
+ << "\ttokenRefreshStartTime: " << Util::getTimeForLog(now, _tokenRefreshStartTime);
+ os << indent << "\ttokenRefreshTimeout: " << _tokenRefreshTimeout;
+ os << indent << "\theader: " << (_noHeader ? "No" : "Yes");
+ }
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/RequestDetailsTests.cpp b/test/RequestDetailsTests.cpp
index afb7ef50f734..3e4c0feb1c85 100644
--- a/test/RequestDetailsTests.cpp
+++ b/test/RequestDetailsTests.cpp
@@ -39,6 +39,7 @@ class RequestDetailsTests : public CPPUNIT_NS::TestFixture
CPPUNIT_TEST(testCoolWs);
CPPUNIT_TEST(testAuthorization);
CPPUNIT_TEST(testAuthorizationExpiry);
+ CPPUNIT_TEST(testAuthorizationDumpState);
CPPUNIT_TEST(testSanitizePercent);

CPPUNIT_TEST_SUITE_END();
@@ -51,6 +52,7 @@ class RequestDetailsTests : public CPPUNIT_NS::TestFixture
void testCoolWs();
void testAuthorization();
void testAuthorizationExpiry();
+ void testAuthorizationDumpState();
void testSanitizePercent();
};

@@ -1468,6 +1470,81 @@ void RequestDetailsTests::testAuthorizationExpiry()
}
}

+void RequestDetailsTests::testAuthorizationDumpState()
+{
+ constexpr std::string_view testname = __func__;
+
+ using duration = std::chrono::milliseconds;
+
+ // Token type should dump type and data.
+ {
+ Authorization auth(Authorization::Type::Token, "secret123", false);
+ std::ostringstream oss;
+ auth.dumpState(oss);
+ const std::string dump = oss.str();
+ LOK_ASSERT_MESSAGE("Should contain token data", dump.find("secret123") != std::string::npos);
+ LOK_ASSERT_MESSAGE("Should contain type", dump.find("Token") != std::string::npos);
+ LOK_ASSERT_MESSAGE("Should contain header info", dump.find("header:") != std::string::npos);
+ }
+
+ // Expired type should show Expired.
+ {
+ Authorization auth(Authorization::Type::Token, "tok", false);
+ auth.expire();
+ std::ostringstream oss;
+ auth.dumpState(oss);
+ LOK_ASSERT_MESSAGE("Should show Expired", oss.str().find("Expired") != std::string::npos);
+ }
+
+ // TokenRefresh type should show TokenRefresh.
+ {
+ Authorization auth(Authorization::Type::Token, "tok", false);
+ auth.startTokenRefresh(std::chrono::seconds(10));
+ std::ostringstream oss;
+ auth.dumpState(oss);
+ LOK_ASSERT_MESSAGE("Should show TokenRefresh",
+ oss.str().find("TokenRefresh") != std::string::npos);
+ }
+
+ // None type should show None.
+ {
+ Authorization auth(Authorization::Type::None, "", false);
+ std::ostringstream oss;
+ auth.dumpState(oss);
+ LOK_ASSERT_MESSAGE("Should show None", oss.str().find("None") != std::string::npos);
+ }
+
+ // Header type should show Header.
+ {
+ Authorization auth(Authorization::Type::Header, "Authorization: Basic abc==", false);
+ std::ostringstream oss;
+ auth.dumpState(oss);
+ LOK_ASSERT_MESSAGE("Should show Header", oss.str().find("Header") != std::string::npos);
+ }
+
+ // With expiry set, dump should contain TTL info.
+ {
+ Authorization auth(Authorization::Type::Token, "tok", false);
+ const auto futureMs = std::chrono::system_clock::now().time_since_epoch() +
+ std::chrono::hours(1);
+ auth.setExpiryEpoch(std::chrono::duration_cast<duration>(futureMs));
+ std::ostringstream oss;
+ auth.dumpState(oss);
+ LOK_ASSERT_MESSAGE("Should contain TTL info", oss.str().find("TTL") != std::string::npos);
+ LOK_ASSERT_MESSAGE("Should contain 'later' for future expiry",
+ oss.str().find("later") != std::string::npos);
+ }
+
+ // noHeader flag should show "No".
+ {
+ Authorization auth(Authorization::Type::Token, "tok", true);
+ std::ostringstream oss;
+ auth.dumpState(oss);
+ LOK_ASSERT_MESSAGE("Should show header: No",
+ oss.str().find("header: No") != std::string::npos);
+ }
+}
+
void RequestDetailsTests::testSanitizePercent()
{
constexpr std::string_view testname = __func__;
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index ef0876791ffb..0cc68cc69f69 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -3621,8 +3621,11 @@ void ClientSession::dumpState(std::ostream& os)
os << "\t\tisLive: " << isLive()
<< "\n\t\tisViewLoaded: " << isViewLoaded()
<< "\n\t\tisDocumentOwner: " << isDocumentOwner()
- << "\n\t\tstate: " << name(_state)
- << "\n\t\tkeyEvents: " << _keyEvents
+ << "\n\t\tstate: " << name(_state);
+
+ _auth.dumpState(os);
+
+ os << "\n\t\tkeyEvents: " << _keyEvents
// << "\n\t\tvisibleArea: " << _clientVisibleArea
<< "\n\t\tclientSelectedPart: " << _clientSelectedPart
<< "\n\t\ttile size Pixel: " << _tileWidthPixel << 'x' << _tileHeightPixel

Reply all
Reply to author
Forward
0 new messages