From c304b59990b44cf0500721ef523228e3f44027cd Mon Sep 17 00:00:00 2001 From: Mattia Codato Date: Tue, 7 Jul 2020 14:23:36 +0200 Subject: [PATCH] Add GetSingleObjectByNameUsingPermissions function --- lib/icinga/apiactions.cpp | 48 +++++++++++++++++++++++++++++---------- lib/icinga/apiactions.hpp | 2 ++ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/lib/icinga/apiactions.cpp b/lib/icinga/apiactions.cpp index f3269d6f9..9f65186f2 100644 --- a/lib/icinga/apiactions.cpp +++ b/lib/icinga/apiactions.cpp @@ -11,6 +11,7 @@ #include "icinga/clusterevents.hpp" #include "remote/apiaction.hpp" #include "remote/apilistener.hpp" +#include "remote/filterutility.hpp" #include "remote/pkiutility.hpp" #include "remote/httputility.hpp" #include "base/utility.hpp" @@ -555,6 +556,30 @@ Dictionary::Ptr ApiActions::GenerateTicket(const ConfigObject::Ptr&, + cn + "'.", additional); } +Value ApiActions::GetSingleObjectByNameUsingPermissions(String type, String value, ApiUser::Ptr user) +{ + Dictionary::Ptr queryParams = new Dictionary(); + queryParams->Set("type", type); + queryParams->Set(type.ToLower(), value); + + QueryDescription qd; + qd.Types.insert(type); + qd.Permission = "objects/query/" + type; + + std::vector objs; + try { + objs = FilterUtility::GetFilterTargets(qd, queryParams, ActionsHandler::AuthenticatedApiUser); + } catch (const std::exception& ex) { + Log(LogCritical, "ApiActions") << DiagnosticInformation(ex); + return nullptr; + } + + if (objs.empty()) + return nullptr; + + return objs.at(0); +}; + Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, const Dictionary::Ptr& params) { @@ -613,8 +638,11 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, nullptr, MacroProcessor::EscapeCallback(), nullptr, false ); - /* Check if endpoint exists */ - Endpoint::Ptr endpointPtr = Endpoint::GetByName(resolved_endpoint); + if (!ActionsHandler::AuthenticatedApiUser) + BOOST_THROW_EXCEPTION(std::invalid_argument("Can't find API user.")); + + /* Get endpoint */ + Endpoint::Ptr endpointPtr = ApiActions::GetSingleObjectByNameUsingPermissions(Endpoint::GetTypeName(), resolved_endpoint, ActionsHandler::AuthenticatedApiUser); if (!endpointPtr) return ApiActions::CreateResult(404, "Can't find a valid endpoint for '" + resolved_endpoint + "'."); @@ -649,19 +677,19 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, }); if (command_type == "CheckCommand") { - CheckCommand::Ptr cmd = CheckCommand::GetByName(resolved_command); + CheckCommand::Ptr cmd = ApiActions::GetSingleObjectByNameUsingPermissions(CheckCommand::GetTypeName(), resolved_command, ActionsHandler::AuthenticatedApiUser); if (!cmd) return ApiActions::CreateResult(404, "Can't find a valid " + command_type + " for '" + resolved_command + "'."); else cmd->Execute(checkable, cr, execMacros, false); } else if (command_type == "EventCommand") { - EventCommand::Ptr cmd = EventCommand::GetByName(resolved_command); + EventCommand::Ptr cmd = ApiActions::GetSingleObjectByNameUsingPermissions(EventCommand::GetTypeName(), resolved_command, ActionsHandler::AuthenticatedApiUser); if (!cmd) return ApiActions::CreateResult(404, "Can't find a valid " + command_type + " for '" + resolved_command + "'."); else cmd->Execute(checkable, execMacros, false); } else if (command_type == "NotificationCommand") { - NotificationCommand::Ptr cmd = NotificationCommand::GetByName(resolved_command); + NotificationCommand::Ptr cmd = ApiActions::GetSingleObjectByNameUsingPermissions(NotificationCommand::GetTypeName(), resolved_command, ActionsHandler::AuthenticatedApiUser); if (!cmd) return ApiActions::CreateResult(404, "Can't find a valid " + command_type + " for '" + resolved_command + "'."); else { @@ -676,7 +704,7 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, MacroProcessor::EscapeCallback(), nullptr, false ); - User::Ptr user = User::GetByName(resolved_user); + User::Ptr user = ApiActions::GetSingleObjectByNameUsingPermissions(User::GetTypeName(), resolved_command, ActionsHandler::AuthenticatedApiUser); if (!user) return ApiActions::CreateResult(404, "Can't find a valid user for '" + resolved_user + "'."); @@ -691,14 +719,10 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, MacroProcessor::EscapeCallback(), nullptr, false ); - Notification::Ptr notification = Notification::GetByName(resolved_notification); - if (!user) + Notification::Ptr notification = ApiActions::GetSingleObjectByNameUsingPermissions(Notification::GetTypeName(), resolved_command, ActionsHandler::AuthenticatedApiUser); + if (!notification) return ApiActions::CreateResult(404, "Can't find a valid notification for '" + resolved_notification + "'."); - /* Get author */ - if (!ActionsHandler::AuthenticatedApiUser) - BOOST_THROW_EXCEPTION(std::invalid_argument("Can't find API user.")); - cmd->Execute(notification, user, cr, NotificationType::NotificationCustom, ActionsHandler::AuthenticatedApiUser->GetName(), "", execMacros, false); } diff --git a/lib/icinga/apiactions.hpp b/lib/icinga/apiactions.hpp index 46e03c02f..c588c7ddc 100644 --- a/lib/icinga/apiactions.hpp +++ b/lib/icinga/apiactions.hpp @@ -6,6 +6,7 @@ #include "icinga/i2-icinga.hpp" #include "base/configobject.hpp" #include "base/dictionary.hpp" +#include "remote/apiuser.hpp" namespace icinga { @@ -33,6 +34,7 @@ public: private: static Dictionary::Ptr CreateResult(int code, const String& status, const Dictionary::Ptr& additional = nullptr); + static Value GetSingleObjectByNameUsingPermissions(String type, String value, ApiUser::Ptr user); }; }