Merge pull request #6685 from Icinga/bugfix/api-permission-filters

Fix regression with API permission filters and namespaces in v2.10
This commit is contained in:
Michael Friedrich 2018-10-15 17:02:14 +02:00 committed by GitHub
commit 3cccc9d9b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 22 additions and 14 deletions

View File

@ -21,6 +21,7 @@
#include "remote/httputility.hpp" #include "remote/httputility.hpp"
#include "config/configcompiler.hpp" #include "config/configcompiler.hpp"
#include "config/expression.hpp" #include "config/expression.hpp"
#include "base/namespace.hpp"
#include "base/json.hpp" #include "base/json.hpp"
#include "base/configtype.hpp" #include "base/configtype.hpp"
#include "base/logger.hpp" #include "base/logger.hpp"
@ -95,16 +96,20 @@ bool FilterUtility::EvaluateFilter(ScriptFrame& frame, Expression *filter,
else else
varName = variableName; varName = variableName;
Dictionary::Ptr vars; Namespace::Ptr frameNS;
if (frame.Self.IsEmpty()) { if (frame.Self.IsEmpty()) {
vars = new Dictionary(); frameNS = new Namespace();
frame.Self = vars; frame.Self = frameNS;
} else } else {
vars = frame.Self; /* Enforce a namespace object for 'frame.self'. */
ASSERT(frame.Self.IsObjectType<Namespace>());
vars->Set("obj", target); frameNS = frame.Self;
vars->Set(varName, target); }
frameNS->Set("obj", target);
frameNS->Set(varName, target);
for (int fid = 0; fid < type->GetFieldCount(); fid++) { for (int fid = 0; fid < type->GetFieldCount(); fid++) {
Field field = type->GetFieldInfo(fid); Field field = type->GetFieldInfo(fid);
@ -115,9 +120,9 @@ bool FilterUtility::EvaluateFilter(ScriptFrame& frame, Expression *filter,
Object::Ptr joinedObj = target->NavigateField(fid); Object::Ptr joinedObj = target->NavigateField(fid);
if (field.NavigationName) if (field.NavigationName)
vars->Set(field.NavigationName, joinedObj); frameNS->Set(field.NavigationName, joinedObj);
else else
vars->Set(field.Name, joinedObj); frameNS->Set(field.Name, joinedObj);
} }
return Convert::ToBool(filter->Evaluate(frame)); return Convert::ToBool(filter->Evaluate(frame));
@ -126,8 +131,11 @@ bool FilterUtility::EvaluateFilter(ScriptFrame& frame, Expression *filter,
static void FilteredAddTarget(ScriptFrame& permissionFrame, Expression *permissionFilter, static void FilteredAddTarget(ScriptFrame& permissionFrame, Expression *permissionFilter,
ScriptFrame& frame, Expression *ufilter, std::vector<Value>& result, const String& variableName, const Object::Ptr& target) ScriptFrame& frame, Expression *ufilter, std::vector<Value>& result, const String& variableName, const Object::Ptr& target)
{ {
if (FilterUtility::EvaluateFilter(permissionFrame, permissionFilter, target, variableName) && FilterUtility::EvaluateFilter(frame, ufilter, target, variableName)) if (FilterUtility::EvaluateFilter(permissionFrame, permissionFilter, target, variableName)) {
result.emplace_back(std::move(target)); if (FilterUtility::EvaluateFilter(frame, ufilter, target, variableName)) {
result.emplace_back(std::move(target));
}
}
} }
void FilterUtility::CheckPermission(const ApiUser::Ptr& user, const String& permission, Expression **permissionFilter) void FilterUtility::CheckPermission(const ApiUser::Ptr& user, const String& permission, Expression **permissionFilter)
@ -249,7 +257,7 @@ std::vector<Value> FilterUtility::GetFilterTargets(const QueryDescription& qd, c
ScriptFrame frame(true); ScriptFrame frame(true);
frame.Sandboxed = true; frame.Sandboxed = true;
Dictionary::Ptr uvars = new Dictionary(); Namespace::Ptr frameNS = new Namespace();
if (query->Contains("filter")) { if (query->Contains("filter")) {
String filter = HttpUtility::GetLastParameter(query, "filter"); String filter = HttpUtility::GetLastParameter(query, "filter");
@ -259,11 +267,11 @@ std::vector<Value> FilterUtility::GetFilterTargets(const QueryDescription& qd, c
if (filter_vars) { if (filter_vars) {
ObjectLock olock(filter_vars); ObjectLock olock(filter_vars);
for (const Dictionary::Pair& kv : filter_vars) { for (const Dictionary::Pair& kv : filter_vars) {
uvars->Set(kv.first, kv.second); frameNS->Set(kv.first, kv.second);
} }
} }
frame.Self = uvars; frame.Self = frameNS;
provider->FindTargets(type, std::bind(&FilteredAddTarget, provider->FindTargets(type, std::bind(&FilteredAddTarget,
std::ref(permissionFrame), permissionFilter, std::ref(permissionFrame), permissionFilter,