Add GetSingleObjectByNameUsingPermissions function

This commit is contained in:
Mattia Codato 2020-07-07 14:23:36 +02:00
parent 704aa0f685
commit c304b59990
2 changed files with 38 additions and 12 deletions

View File

@ -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<Value> 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);
}

View File

@ -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);
};
}