diff --git a/lib/remote/filterutility.cpp b/lib/remote/filterutility.cpp index 9bcc60f7112..e380cb1e4d6 100644 --- a/lib/remote/filterutility.cpp +++ b/lib/remote/filterutility.cpp @@ -115,7 +115,7 @@ bool FilterUtility::EvaluateFilter(ScriptFrame& frame, Expression *filter, } static void FilteredAddTarget(ScriptFrame& permissionFrame, Expression *permissionFilter, - ScriptFrame& frame, Expression *ufilter, std::vector& result, const String& variableName, const Object::Ptr& target) + ScriptFrame& frame, Expression* ufilter, std::vector& result, const String& variableName, const Object::Ptr& target) { if (FilterUtility::EvaluateFilter(permissionFrame, permissionFilter, target, variableName)) { if (FilterUtility::EvaluateFilter(frame, ufilter, target, variableName)) { @@ -138,7 +138,7 @@ static void FilteredAddTarget(ScriptFrame& permissionFrame, Expression *permissi * * @return bool */ -bool FilterUtility::HasPermission(const ApiUser::Ptr& user, const String& permission, Expression **permissionFilter) +bool FilterUtility::HasPermission(const ApiUser::Ptr& user, const String& permission, Expression::Ptr* permissionFilter) { if (permissionFilter) *permissionFilter = nullptr; @@ -149,6 +149,7 @@ bool FilterUtility::HasPermission(const ApiUser::Ptr& user, const String& permis bool foundPermission = false; String requiredPermission = permission.ToLower(); + std::unique_ptr filtersBuffer; Array::Ptr permissions = user->GetPermissions(); if (permissions) { ObjectLock olock(permissions); @@ -175,14 +176,18 @@ bool FilterUtility::HasPermission(const ApiUser::Ptr& user, const String& permis std::unique_ptr indexer{new IndexerExpression(std::unique_ptr(MakeLiteral(filter)), std::unique_ptr(MakeLiteral("call")))}; FunctionCallExpression *fexpr = new FunctionCallExpression(std::move(indexer), std::move(args)); - if (!*permissionFilter) - *permissionFilter = fexpr; + if (!filtersBuffer) + filtersBuffer.reset(fexpr); else - *permissionFilter = new LogicalOrExpression(std::unique_ptr(*permissionFilter), std::unique_ptr(fexpr)); + filtersBuffer = std::make_unique(std::move(filtersBuffer), std::unique_ptr(fexpr)); } } } + if (permissionFilter) { + *permissionFilter = filtersBuffer.release(); + } + if (!foundPermission) { Log(LogWarning, "FilterUtility") << "Missing permission: " << requiredPermission; @@ -191,7 +196,7 @@ bool FilterUtility::HasPermission(const ApiUser::Ptr& user, const String& permis return foundPermission; } -void FilterUtility::CheckPermission(const ApiUser::Ptr& user, const String& permission, Expression **permissionFilter) +void FilterUtility::CheckPermission(const ApiUser::Ptr& user, const String& permission, Expression::Ptr* permissionFilter) { if (!HasPermission(user, permission, permissionFilter)) { BOOST_THROW_EXCEPTION(ScriptError("Missing permission: " + permission.ToLower())); @@ -209,7 +214,7 @@ std::vector FilterUtility::GetFilterTargets(const QueryDescription& qd, c else provider = new ConfigObjectTargetProvider(); - Expression *permissionFilter; + Expression::Ptr permissionFilter; CheckPermission(user, qd.Permission, &permissionFilter); Namespace::Ptr permissionFrameNS = new Namespace(); @@ -226,7 +231,7 @@ std::vector FilterUtility::GetFilterTargets(const QueryDescription& qd, c String name = HttpUtility::GetLastParameter(query, attr); Object::Ptr target = provider->GetTargetByName(type, name); - if (!FilterUtility::EvaluateFilter(permissionFrame, permissionFilter, target, variableName)) + if (!FilterUtility::EvaluateFilter(permissionFrame, permissionFilter.get(), target, variableName)) BOOST_THROW_EXCEPTION(ScriptError("Access denied to object '" + name + "' of type '" + type + "'")); result.emplace_back(std::move(target)); @@ -242,7 +247,7 @@ std::vector FilterUtility::GetFilterTargets(const QueryDescription& qd, c for (const String& name : names) { Object::Ptr target = provider->GetTargetByName(type, name); - if (!FilterUtility::EvaluateFilter(permissionFrame, permissionFilter, target, variableName)) + if (!FilterUtility::EvaluateFilter(permissionFrame, permissionFilter.get(), target, variableName)) BOOST_THROW_EXCEPTION(ScriptError("Access denied to object '" + name + "' of type '" + type + "'")); result.emplace_back(std::move(target)); @@ -279,15 +284,15 @@ std::vector FilterUtility::GetFilterTargets(const QueryDescription& qd, c } } - provider->FindTargets(type, [&permissionFrame, permissionFilter, &frame, &ufilter, &result, variableName](const Object::Ptr& target) { - FilteredAddTarget(permissionFrame, permissionFilter, frame, &*ufilter, result, variableName, target); + provider->FindTargets(type, [&permissionFrame, &permissionFilter, &frame, &ufilter, &result, variableName](const Object::Ptr& target) { + FilteredAddTarget(permissionFrame, permissionFilter.get(), frame, &*ufilter, result, variableName, target); }); } else { /* Ensure to pass a nullptr as filter expression. * GCC 8.1.1 on F28 causes problems, see GH #6533. */ - provider->FindTargets(type, [&permissionFrame, permissionFilter, &frame, &result, variableName](const Object::Ptr& target) { - FilteredAddTarget(permissionFrame, permissionFilter, frame, nullptr, result, variableName, target); + provider->FindTargets(type, [&permissionFrame, &permissionFilter, &frame, &result, variableName](const Object::Ptr& target) { + FilteredAddTarget(permissionFrame, permissionFilter.get(), frame, nullptr, result, variableName, target); }); } } diff --git a/lib/remote/filterutility.hpp b/lib/remote/filterutility.hpp index 1cebffc0bf8..e1093df916a 100644 --- a/lib/remote/filterutility.hpp +++ b/lib/remote/filterutility.hpp @@ -51,8 +51,8 @@ class FilterUtility { public: static Type::Ptr TypeFromPluralName(const String& pluralName); - static void CheckPermission(const ApiUser::Ptr& user, const String& permission, Expression **filter = nullptr); - static bool HasPermission(const ApiUser::Ptr& user, const String& permission, Expression **permissionFilter = nullptr); + static void CheckPermission(const ApiUser::Ptr& user, const String& permission, Expression::Ptr* filter = nullptr); + static bool HasPermission(const ApiUser::Ptr& user, const String& permission, Expression::Ptr* permissionFilter = nullptr); static std::vector GetFilterTargets(const QueryDescription& qd, const Dictionary::Ptr& query, const ApiUser::Ptr& user, const String& variableName = String()); static bool EvaluateFilter(ScriptFrame& frame, Expression *filter, diff --git a/lib/remote/objectqueryhandler.cpp b/lib/remote/objectqueryhandler.cpp index f059c03280f..227495e0523 100644 --- a/lib/remote/objectqueryhandler.cpp +++ b/lib/remote/objectqueryhandler.cpp @@ -270,9 +270,7 @@ bool ObjectQueryHandler::HandleRequest( if (it == typePermissions.end()) { String permission = "objects/query/" + reflectionType->GetName(); - Expression *filter = nullptr; - granted = FilterUtility::HasPermission(user, permission, &filter); - permissionFilter = filter; + granted = FilterUtility::HasPermission(user, permission, &permissionFilter); typePermissions.insert({reflectionType.get(), std::make_pair(granted, permissionFilter)}); } else {