diff --git a/src/agent/communicator/include/ihttp_client.hpp b/src/agent/communicator/include/ihttp_client.hpp index b75ad52bd5..e4a245c6a0 100644 --- a/src/agent/communicator/include/ihttp_client.hpp +++ b/src/agent/communicator/include/ihttp_client.hpp @@ -45,7 +45,8 @@ namespace http_client bool operator==(const HttpRequestParams& other) const { return Method == other.Method && Host == other.Host && Port == other.Port && Endpoint == other.Endpoint && - Token == other.Token && User_pass == other.User_pass && Body == other.Body && Use_Https == other.Use_Https; + Token == other.Token && User_pass == other.User_pass && Body == other.Body && + Use_Https == other.Use_Https; } }; diff --git a/src/agent/communicator/include/ihttp_socket_factory.hpp b/src/agent/communicator/include/ihttp_socket_factory.hpp index d1dd80b80c..3a5529490a 100644 --- a/src/agent/communicator/include/ihttp_socket_factory.hpp +++ b/src/agent/communicator/include/ihttp_socket_factory.hpp @@ -12,6 +12,7 @@ namespace http_client { public: virtual ~IHttpSocketFactory() = default; - virtual std::unique_ptr Create(const boost::asio::any_io_executor& executor, const bool use_https) = 0; + virtual std::unique_ptr Create(const boost::asio::any_io_executor& executor, + const bool use_https) = 0; }; } // namespace http_client diff --git a/src/agent/communicator/src/communicator.cpp b/src/agent/communicator/src/communicator.cpp index 968d85c758..89b7b2411b 100644 --- a/src/agent/communicator/src/communicator.cpp +++ b/src/agent/communicator/src/communicator.cpp @@ -41,8 +41,9 @@ namespace communicator { m_managerIp = getStringConfigValue("agent", "manager_ip"); m_port = getStringConfigValue("agent", "agent_comms_api_port"); - const std::string httpsEnabled = getStringConfigValue("agent", "https_enabled"); - if (httpsEnabled == "no") { + const std::string httpsEnabled = getStringConfigValue("agent", "https_enabled"); + if (httpsEnabled == "no") + { m_useHttps = false; LogInfo("Using insecure connection."); } @@ -100,8 +101,8 @@ namespace communicator return m_keepRunning.load(); }; - const auto reqParams = - http_client::HttpRequestParams(boost::beast::http::verb::get, m_managerIp, m_port, "/api/v1/commands", m_useHttps); + const auto reqParams = http_client::HttpRequestParams( + boost::beast::http::verb::get, m_managerIp, m_port, "/api/v1/commands", m_useHttps); co_await m_httpClient->Co_PerformHttpRequest( m_token, reqParams, {}, onAuthenticationFailed, onSuccess, loopCondition); } diff --git a/src/agent/communicator/src/http_socket_factory.hpp b/src/agent/communicator/src/http_socket_factory.hpp index f82ae7e641..0b621c1e95 100644 --- a/src/agent/communicator/src/http_socket_factory.hpp +++ b/src/agent/communicator/src/http_socket_factory.hpp @@ -14,8 +14,7 @@ namespace http_client class HttpSocketFactory : public IHttpSocketFactory { public: - std::unique_ptr Create(const boost::asio::any_io_executor& executor, - const bool use_https) override + std::unique_ptr Create(const boost::asio::any_io_executor& executor, const bool use_https) override { if (use_https) return std::make_unique(executor); diff --git a/src/agent/communicator/src/https_socket.hpp b/src/agent/communicator/src/https_socket.hpp index 1232ddd69e..a565b32ed5 100644 --- a/src/agent/communicator/src/https_socket.hpp +++ b/src/agent/communicator/src/https_socket.hpp @@ -1,8 +1,8 @@ #include #include -#include #include +#include namespace http_client { @@ -10,8 +10,8 @@ namespace http_client { public: HttpsSocket(const boost::asio::any_io_executor& io_context) - : m_ctx(boost::asio::ssl::context::sslv23), - m_ssl_socket(io_context, m_ctx) + : m_ctx(boost::asio::ssl::context::sslv23) + , m_ssl_socket(io_context, m_ctx) { m_ctx.set_verify_mode(boost::asio::ssl::verify_peer); } @@ -29,8 +29,8 @@ namespace http_client co_await boost::asio::async_connect( m_ssl_socket.lowest_layer(), endpoints, boost::asio::redirect_error(boost::asio::use_awaitable, code)); - co_await m_ssl_socket.async_handshake( - boost::asio::ssl::stream_base::client, boost::asio::redirect_error(boost::asio::use_awaitable, code)); + co_await m_ssl_socket.async_handshake(boost::asio::ssl::stream_base::client, + boost::asio::redirect_error(boost::asio::use_awaitable, code)); } void Write(const boost::beast::http::request& req) override diff --git a/src/agent/communicator/tests/communicator_test.cpp b/src/agent/communicator/tests/communicator_test.cpp index 470ee85bc2..946a49dbb1 100644 --- a/src/agent/communicator/tests/communicator_test.cpp +++ b/src/agent/communicator/tests/communicator_test.cpp @@ -80,12 +80,13 @@ TEST(CommunicatorTest, WaitForTokenExpirationAndAuthenticate_FailedAuthenticatio std::make_shared(std::move(mockHttpClient), "uuid", "key", nullptr); // A failed authentication won't return a token - EXPECT_CALL(*mockHttpClientPtr, AuthenticateWithUuidAndKey(_, _, _, _)) + EXPECT_CALL(*mockHttpClientPtr, AuthenticateWithUuidAndKey(_, _, _, _, _)) .WillOnce(Invoke( [communicatorPtr]([[maybe_unused]] const std::string& host, [[maybe_unused]] const std::string& port, [[maybe_unused]] const std::string& uuid, - [[maybe_unused]] const std::string& key) -> std::optional + [[maybe_unused]] const std::string& key, + [[maybe_unused]] const bool useHttps) -> std::optional { communicatorPtr->Stop(); return std::nullopt; @@ -138,7 +139,7 @@ TEST(CommunicatorTest, StatelessMessageProcessingTask_CallsWithValidToken) std::make_shared(std::move(mockHttpClient), "uuid", "key", nullptr); const auto mockedToken = CreateToken(); - EXPECT_CALL(*mockHttpClientPtr, AuthenticateWithUuidAndKey(_, _, _, _)).WillOnce(Return(mockedToken)); + EXPECT_CALL(*mockHttpClientPtr, AuthenticateWithUuidAndKey(_, _, _, _, _)).WillOnce(Return(mockedToken)); std::string capturedToken; EXPECT_CALL(*mockHttpClientPtr, Co_PerformHttpRequest(_, _, _, _, _, _)) diff --git a/src/agent/communicator/tests/http_client_test.cpp b/src/agent/communicator/tests/http_client_test.cpp index d4535926ac..858cd9fdb4 100644 --- a/src/agent/communicator/tests/http_client_test.cpp +++ b/src/agent/communicator/tests/http_client_test.cpp @@ -42,9 +42,10 @@ class HttpClientTest : public Test void SetupMockSocketFactory() { - EXPECT_CALL(*mockSocketFactory, Create(_)) + EXPECT_CALL(*mockSocketFactory, Create(_, _)) .WillOnce(Invoke( - [&](const auto& executor) -> std::unique_ptr + [&](const auto& executor, + [[maybe_unused]] const bool useHttps) -> std::unique_ptr { EXPECT_TRUE(executor); return std::move(mockSocket); @@ -106,7 +107,8 @@ class HttpClientTest : public Test TEST(CreateHttpRequestTest, BasicGetRequest) { auto httpClient = http_client::HttpClient(); - const auto reqParams = http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/test"); + const auto reqParams = + http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/test", true); const auto req = httpClient.CreateHttpRequest(reqParams); EXPECT_EQ(req.method(), boost::beast::http::verb::get); @@ -121,8 +123,8 @@ TEST(CreateHttpRequestTest, PostRequestWithBody) { auto httpClient = http_client::HttpClient(); const std::string body = R"({"key": "value"})"; - const auto reqParams = - http_client::HttpRequestParams(boost::beast::http::verb::post, "localhost", "8080", "/submit", "", "", body); + const auto reqParams = http_client::HttpRequestParams( + boost::beast::http::verb::post, "localhost", "8080", "/submit", false, "", "", body); const auto req = httpClient.CreateHttpRequest(reqParams); EXPECT_EQ(req.method(), boost::beast::http::verb::post); @@ -140,7 +142,7 @@ TEST(CreateHttpRequestTest, AuthorizationBearerToken) auto httpClient = http_client::HttpClient(); const std::string token = "dummy_token"; const auto reqParams = - http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/secure", token); + http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/secure", true, token); const auto req = httpClient.CreateHttpRequest(reqParams); EXPECT_EQ(req[boost::beast::http::field::authorization], "Bearer dummy_token"); @@ -150,8 +152,8 @@ TEST(CreateHttpRequestTest, AuthorizationBasic) { auto httpClient = http_client::HttpClient(); const std::string user_pass = "username:password"; - const auto reqParams = - http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/secure", "", user_pass); + const auto reqParams = http_client::HttpRequestParams( + boost::beast::http::verb::get, "localhost", "8080", "/secure", true, "", user_pass); const auto req = httpClient.CreateHttpRequest(reqParams); EXPECT_EQ(req[boost::beast::http::field::authorization], "Basic username:password"); @@ -167,7 +169,7 @@ TEST_F(HttpClientTest, PerformHttpRequest_Success) EXPECT_CALL(*mockSocket, Write(_)).Times(1); EXPECT_CALL(*mockSocket, Read(_)).WillOnce([](auto& res) { res.result(boost::beast::http::status::ok); }); - const http_client::HttpRequestParams params(boost::beast::http::verb::get, "localhost", "80", "/"); + const http_client::HttpRequestParams params(boost::beast::http::verb::get, "localhost", "80", "/", true); const auto response = client->PerformHttpRequest(params); EXPECT_EQ(response.result(), boost::beast::http::status::ok); @@ -179,7 +181,7 @@ TEST_F(HttpClientTest, PerformHttpRequest_ExceptionThrown) EXPECT_CALL(*mockResolver, Resolve(_, _)).WillOnce(Throw(std::runtime_error("Simulated resolution failure"))); - const http_client::HttpRequestParams params(boost::beast::http::verb::get, "localhost", "80", "/"); + const http_client::HttpRequestParams params(boost::beast::http::verb::get, "localhost", "80", "/", true); const auto response = client->PerformHttpRequest(params); EXPECT_EQ(response.result(), boost::beast::http::status::internal_server_error); @@ -216,7 +218,9 @@ TEST_F(HttpClientTest, Co_PerformHttpRequest_Success) unauthorizedCalled = true; }; - const auto reqParams = http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/"); + const auto reqParams = + http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/", true); + auto task = client->Co_PerformHttpRequest( std::make_shared("token"), reqParams, getMessages, onUnauthorized, onSuccess, nullptr); @@ -256,7 +260,8 @@ TEST_F(HttpClientTest, Co_PerformHttpRequest_CallbacksNotCalledIfCannotConnect) unauthorizedCalled = true; }; - const auto reqParams = http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/"); + const auto reqParams = + http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/", true); auto task = client->Co_PerformHttpRequest( std::make_shared("token"), reqParams, getMessages, onUnauthorized, onSuccess, nullptr); @@ -297,7 +302,8 @@ TEST_F(HttpClientTest, Co_PerformHttpRequest_OnSuccessNotCalledIfAsyncWriteFails unauthorizedCalled = true; }; - const auto reqParams = http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/"); + const auto reqParams = + http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/", true); auto task = client->Co_PerformHttpRequest( std::make_shared("token"), reqParams, getMessages, onUnauthorized, onSuccess, nullptr); @@ -340,7 +346,8 @@ TEST_F(HttpClientTest, Co_PerformHttpRequest_OnSuccessNotCalledIfAsyncReadFails) unauthorizedCalled = true; }; - const auto reqParams = http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/"); + const auto reqParams = + http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/", true); auto task = client->Co_PerformHttpRequest( std::make_shared("token"), reqParams, getMessages, onUnauthorized, onSuccess, nullptr); @@ -382,7 +389,8 @@ TEST_F(HttpClientTest, Co_PerformHttpRequest_UnauthorizedCalledWhenAuthorization unauthorizedCalled = true; }; - const auto reqParams = http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/"); + const auto reqParams = + http_client::HttpRequestParams(boost::beast::http::verb::get, "localhost", "8080", "/", true); auto task = client->Co_PerformHttpRequest( std::make_shared("token"), reqParams, getMessages, onUnauthorized, onSuccess, nullptr); @@ -411,7 +419,7 @@ TEST_F(HttpClientTest, AuthenticateWithUuidAndKey_Success) boost::beast::ostream(res.body()) << R"({"token":"valid_token"})"; }); - const auto token = client->AuthenticateWithUuidAndKey("localhost", "8080", "test-uuid", "test-key"); + const auto token = client->AuthenticateWithUuidAndKey("localhost", "8080", "test-uuid", "test-key", true); ASSERT_TRUE(token.has_value()); @@ -429,7 +437,7 @@ TEST_F(HttpClientTest, AuthenticateWithUuidAndKey_Failure) EXPECT_CALL(*mockSocket, Write(_)).Times(1); EXPECT_CALL(*mockSocket, Read(_)).WillOnce([](auto& res) { res.result(boost::beast::http::status::unauthorized); }); - const auto token = client->AuthenticateWithUuidAndKey("localhost", "8080", "test-uuid", "test-key"); + const auto token = client->AuthenticateWithUuidAndKey("localhost", "8080", "test-uuid", "test-key", true); EXPECT_FALSE(token.has_value()); } @@ -450,7 +458,7 @@ TEST_F(HttpClientTest, AuthenticateWithUserPassword_Success) boost::beast::ostream(res.body()) << R"({"data":{"token":"valid_token"}})"; }); - const auto token = client->AuthenticateWithUserPassword("localhost", "8080", "user", "password"); + const auto token = client->AuthenticateWithUserPassword("localhost", "8080", "user", "password", true); ASSERT_TRUE(token.has_value()); @@ -468,7 +476,7 @@ TEST_F(HttpClientTest, AuthenticateWithUserPassword_Failure) EXPECT_CALL(*mockSocket, Write(_)).Times(1); EXPECT_CALL(*mockSocket, Read(_)).WillOnce([](auto& res) { res.result(boost::beast::http::status::unauthorized); }); - const auto token = client->AuthenticateWithUserPassword("localhost", "8080", "user", "password"); + const auto token = client->AuthenticateWithUserPassword("localhost", "8080", "user", "password", true); EXPECT_FALSE(token.has_value()); } diff --git a/src/agent/communicator/tests/mocks/mock_http_client.hpp b/src/agent/communicator/tests/mocks/mock_http_client.hpp index fa51708f61..bd110eccaa 100644 --- a/src/agent/communicator/tests/mocks/mock_http_client.hpp +++ b/src/agent/communicator/tests/mocks/mock_http_client.hpp @@ -27,12 +27,19 @@ class MockHttpClient : public http_client::IHttpClient MOCK_METHOD(std::optional, AuthenticateWithUuidAndKey, - (const std::string& host, const std::string& port, const std::string& uuid, const std::string& key), + (const std::string& host, + const std::string& port, + const std::string& uuid, + const std::string& key, + const bool useHttps), (override)); - MOCK_METHOD( - std::optional, - AuthenticateWithUserPassword, - (const std::string& host, const std::string& port, const std::string& user, const std::string& password), - (override)); + MOCK_METHOD(std::optional, + AuthenticateWithUserPassword, + (const std::string& host, + const std::string& port, + const std::string& user, + const std::string& password, + const bool useHttps), + (override)); }; diff --git a/src/agent/communicator/tests/mocks/mock_http_socket_factory.hpp b/src/agent/communicator/tests/mocks/mock_http_socket_factory.hpp index 3781a67029..27cbba4392 100644 --- a/src/agent/communicator/tests/mocks/mock_http_socket_factory.hpp +++ b/src/agent/communicator/tests/mocks/mock_http_socket_factory.hpp @@ -8,6 +8,6 @@ class MockHttpSocketFactory : public http_client::IHttpSocketFactory public: MOCK_METHOD(std::unique_ptr, Create, - (const boost::asio::any_io_executor& executor), + (const boost::asio::any_io_executor& executor, const bool use_https), (override)); }; diff --git a/src/agent/tests/register_test.cpp b/src/agent/tests/register_test.cpp index bdcc6b7006..8a620f3a6d 100644 --- a/src/agent/tests/register_test.cpp +++ b/src/agent/tests/register_test.cpp @@ -39,14 +39,21 @@ class MockHttpClient : public http_client::IHttpClient MOCK_METHOD(std::optional, AuthenticateWithUuidAndKey, - (const std::string& host, const std::string& port, const std::string& uuid, const std::string& key), + (const std::string& host, + const std::string& port, + const std::string& uuid, + const std::string& key, + const bool useHttps), (override)); - MOCK_METHOD( - std::optional, - AuthenticateWithUserPassword, - (const std::string& host, const std::string& port, const std::string& user, const std::string& password), - (override)); + MOCK_METHOD(std::optional, + AuthenticateWithUserPassword, + (const std::string& host, + const std::string& port, + const std::string& user, + const std::string& password, + const bool useHttps), + (override)); }; class RegisterTest : public ::testing::Test @@ -65,7 +72,13 @@ class RegisterTest : public ::testing::Test TEST_F(RegisterTest, RegistrationTestSuccess) { EXPECT_CALL(mockHttpClient, - AuthenticateWithUserPassword(testing::_, testing::_, userCredentials.user, userCredentials.password)) + AuthenticateWithUserPassword( + testing::_, testing::_, userCredentials.user, userCredentials.password, testing::_)) + .WillOnce(testing::Return("token")); + + EXPECT_CALL(mockHttpClient, + AuthenticateWithUserPassword( + testing::_, testing::_, userCredentials.user, userCredentials.password, testing::_)) .WillOnce(testing::Return("token")); nlohmann::json bodyJson = {{"id", agent->GetUUID()}, {"key", agent->GetKey()}}; @@ -76,7 +89,7 @@ TEST_F(RegisterTest, RegistrationTestSuccess) } http_client::HttpRequestParams reqParams( - boost::beast::http::verb::post, "localhost", "55000", "/agents", "token", "", bodyJson.dump()); + boost::beast::http::verb::post, "localhost", "55000", "/agents", true, "token", "", bodyJson.dump()); boost::beast::http::response expectedResponse; expectedResponse.result(boost::beast::http::status::ok); @@ -90,7 +103,8 @@ TEST_F(RegisterTest, RegistrationTestSuccess) TEST_F(RegisterTest, RegistrationFailsIfAuthenticationFails) { - EXPECT_CALL(mockHttpClient, AuthenticateWithUserPassword(testing::_, testing::_, testing::_, testing::_)) + EXPECT_CALL(mockHttpClient, + AuthenticateWithUserPassword(testing::_, testing::_, testing::_, testing::_, testing::_)) .WillOnce(testing::Return(std::nullopt)); // NOLINTNEXTLINE(cppcoreguidelines-init-variables) @@ -101,7 +115,8 @@ TEST_F(RegisterTest, RegistrationFailsIfAuthenticationFails) TEST_F(RegisterTest, RegistrationFailsIfServerResponseIsNotOk) { EXPECT_CALL(mockHttpClient, - AuthenticateWithUserPassword(testing::_, testing::_, userCredentials.user, userCredentials.password)) + AuthenticateWithUserPassword( + testing::_, testing::_, userCredentials.user, userCredentials.password, testing::_)) .WillOnce(testing::Return("token")); boost::beast::http::response expectedResponse;