<< "object ApiUser \"" << api_username << "\" {\n"
<< " password = \"" << api_password << "\"\n"
<< " //client_cn = \"\"\n"
+ << "\n"
+ << " permissions = [ \"*\" ]\n"
<< "}\n";
fp.close();
const std::vector<String>& types = action->GetTypes();
std::vector<Value> objs;
+ String permission = "actions/" + actionName;
+
if (!types.empty()) {
qd.Types = std::set<String>(types.begin(), types.end());
+ qd.Permission = permission;
try {
- objs = FilterUtility::GetFilterTargets(qd, params);
+ objs = FilterUtility::GetFilterTargets(qd, params, user);
} catch (const std::exception& ex) {
HttpUtility::SendJsonError(response, 400,
"Type/Filter was required but not provided or was invalid.",
request.GetVerboseErrors() ? DiagnosticInformation(ex) : "");
return true;
}
- } else
+ } else {
+ FilterUtility::CheckPermission(user, permission);
objs.push_back(ConfigObject::Ptr());
+ }
Array::Ptr results = new Array();
REGISTER_TYPE(ApiUser);
-String ApiUser::GetPassword(void) const
-{
- return "*****";
-}
-
-void ApiUser::SetPassword(const String& password)
-{
- SetPasswordRaw(password);
-}
-
-bool ApiUser::CheckPassword(const String& password) const
-{
- return password == GetPasswordRaw();
-}
-
ApiUser::Ptr ApiUser::GetByClientCN(const String& cn)
{
BOOST_FOREACH(const ApiUser::Ptr& user, ConfigType::GetObjectsByType<ApiUser>()) {
DECLARE_OBJECT(ApiUser);
DECLARE_OBJECTNAME(ApiUser);
- String GetPassword(void) const;
- void SetPassword(const String& password);
- bool CheckPassword(const String& password) const;
-
static ApiUser::Ptr GetByClientCN(const String& cn);
};
******************************************************************************/
#include "base/configobject.hpp"
+#include "base/function.hpp"
library remote;
class ApiUser : ConfigObject
{
- [config, protected] String password (PasswordRaw);
+ [config] String password;
[config] String client_cn (ClientCN);
+ [config] array(Value) permissions;
+};
+
+validator ApiUser {
+ Array permissions {
+ String "*";
+ Dictionary "*" {
+ required permission;
+ String permission;
+ Function filter;
+ };
+ };
};
}
#include "remote/configfileshandler.hpp"
#include "remote/configpackageutility.hpp"
#include "remote/httputility.hpp"
+#include "remote/filterutility.hpp"
#include "base/exception.hpp"
#include <boost/algorithm/string/join.hpp>
#include <fstream>
params->Set("path", boost::algorithm::join(tmpPath, "/"));
}
+ FilterUtility::CheckPermission(user, "config/query");
+
String packageName = HttpUtility::GetLastParameter(params, "package");
String stageName = HttpUtility::GetLastParameter(params, "stage");
#include "remote/configpackageshandler.hpp"
#include "remote/configpackageutility.hpp"
#include "remote/httputility.hpp"
+#include "remote/filterutility.hpp"
#include "base/exception.hpp"
#include <boost/algorithm/string/join.hpp>
void ConfigPackagesHandler::HandleGet(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
+ FilterUtility::CheckPermission(user, "config/query");
+
std::vector<String> packages = ConfigPackageUtility::GetPackages();
Array::Ptr results = new Array();
void ConfigPackagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
+ FilterUtility::CheckPermission(user, "config/modify");
+
Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);
if (request.RequestUrl->GetPath().size() >= 4)
void ConfigPackagesHandler::HandleDelete(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
+ FilterUtility::CheckPermission(user, "config/modify");
+
Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);
if (request.RequestUrl->GetPath().size() >= 4)
#include "remote/configstageshandler.hpp"
#include "remote/configpackageutility.hpp"
#include "remote/httputility.hpp"
+#include "remote/filterutility.hpp"
#include "base/application.hpp"
#include "base/exception.hpp"
#include <boost/foreach.hpp>
void ConfigStagesHandler::HandleGet(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
+ FilterUtility::CheckPermission(user, "config/query");
+
Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);
if (request.RequestUrl->GetPath().size() >= 4)
void ConfigStagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
+ FilterUtility::CheckPermission(user, "config/modify");
+
Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);
if (request.RequestUrl->GetPath().size() >= 4)
void ConfigStagesHandler::HandleDelete(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
+ FilterUtility::CheckPermission(user, "config/modify");
+
Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);
if (request.RequestUrl->GetPath().size() >= 4)
return true;
}
+ FilterUtility::CheckPermission(user, "objects/create/" + type->GetName());
+
String name = request.RequestUrl->GetPath()[3];
Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);
Array::Ptr templates = params->Get("templates");
params->Set(attr, request.RequestUrl->GetPath()[3]);
}
- std::vector<Value> objs = FilterUtility::GetFilterTargets(qd, params);
+ std::vector<Value> objs = FilterUtility::GetFilterTargets(qd, params, user);
bool cascade = HttpUtility::GetLastParameter(params, "cascade");
return Type::GetByName(type)->GetPluralName();
}
-static void FilteredAddTarget(ScriptFrame& frame, Expression *ufilter, std::vector<Value>& result, const Object::Ptr& target)
+static bool EvaluateFilter(ScriptFrame& frame, Expression *filter, const Object::Ptr& target)
{
+ if (!filter)
+ return true;
+
Type::Ptr type = target->GetReflectionType();
- String varName = type->GetName();
- boost::algorithm::to_lower(varName);
+ String varName = type->GetName().ToLower();
+
+ Dictionary::Ptr vars;
+
+ if (frame.Self.IsEmpty()) {
+ vars = new Dictionary();
+ frame.Self = vars;
+ } else
+ vars = frame.Self;
- frame.Locals->Set(varName, target);
+ vars->Set(varName, target);
for (int fid = 0; fid < type->GetFieldCount(); fid++) {
Field field = type->GetFieldInfo(fid);
varName = field.TypeName;
boost::algorithm::to_lower(varName);
- frame.Locals->Set(varName, joinedObj);
+ vars->Set(varName, joinedObj);
}
- if (Convert::ToBool(ufilter->Evaluate(frame)))
+ return Convert::ToBool(filter->Evaluate(frame));
+}
+
+static void FilteredAddTarget(ScriptFrame& permissionFrame, Expression *permissionFilter,
+ ScriptFrame& frame, Expression *ufilter, std::vector<Value>& result, const Object::Ptr& target)
+{
+ if (EvaluateFilter(permissionFrame, permissionFilter, target) && EvaluateFilter(frame, ufilter, target))
result.push_back(target);
}
-std::vector<Value> FilterUtility::GetFilterTargets(const QueryDescription& qd, const Dictionary::Ptr& query)
+void FilterUtility::CheckPermission(const ApiUser::Ptr& user, const String& permission, Expression **permissionFilter)
+{
+ if (permissionFilter)
+ *permissionFilter = NULL;
+
+ if (permission.IsEmpty())
+ return;
+
+ bool foundPermission = false;
+ String requiredPermission = permission.ToLower();
+
+ Array::Ptr permissions = user->GetPermissions();
+ if (permissions) {
+ ObjectLock olock(permissions);
+ BOOST_FOREACH(const Value& item, permissions) {
+ String permission;
+ Function::Ptr filter;
+ if (item.IsObjectType<Dictionary>()) {
+ Dictionary::Ptr dict = item;
+ permission = dict->Get("permission");
+ filter = dict->Get("filter");
+ } else
+ permission = item;
+
+ permission = permission.ToLower();
+
+ if (!Utility::Match(permission, requiredPermission))
+ continue;
+
+ foundPermission = true;
+
+ if (filter && permissionFilter) {
+ std::vector<Expression *> args;
+ args.push_back(new GetScopeExpression(ScopeLocal));
+ FunctionCallExpression *fexpr = new FunctionCallExpression(new IndexerExpression(MakeLiteral(filter), MakeLiteral("call")), args);
+
+ if (!*permissionFilter)
+ *permissionFilter = fexpr;
+ else
+ *permissionFilter = new LogicalOrExpression(*permissionFilter, fexpr);
+ }
+ }
+ }
+
+ if (!foundPermission)
+ BOOST_THROW_EXCEPTION(ScriptError("Missing permission: " + requiredPermission));
+}
+
+std::vector<Value> FilterUtility::GetFilterTargets(const QueryDescription& qd, const Dictionary::Ptr& query, const ApiUser::Ptr& user)
{
std::vector<Value> result;
else
provider = new ConfigObjectTargetProvider();
+ Expression *permissionFilter;
+ CheckPermission(user, qd.Permission, &permissionFilter);
+
+ ScriptFrame permissionFrame;
+
BOOST_FOREACH(const String& type, qd.Types) {
String attr = type;
boost::algorithm::to_lower(attr);
if (attr == "type")
attr = "name";
- if (query->Contains(attr))
- result.push_back(provider->GetTargetByName(type, HttpUtility::GetLastParameter(query, attr)));
+ if (query->Contains(attr)) {
+ Object::Ptr target = provider->GetTargetByName(type, HttpUtility::GetLastParameter(query, attr));
+
+ if (EvaluateFilter(permissionFrame, permissionFilter, target))
+ result.push_back(target);
+ }
attr = provider->GetPluralName(type);
boost::algorithm::to_lower(attr);
if (names) {
ObjectLock olock(names);
BOOST_FOREACH(const String& name, names) {
- result.push_back(provider->GetTargetByName(type, name));
+ Object::Ptr target = provider->GetTargetByName(type, name);
+
+ if (EvaluateFilter(permissionFrame, permissionFilter, target))
+ result.push_back(target);
}
}
}
if (qd.Types.find(type) == qd.Types.end())
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid type specified for this query."));
- Expression *ufilter = ConfigCompiler::CompileText("<API query>", filter);
ScriptFrame frame;
frame.Sandboxed = true;
+ Dictionary::Ptr uvars = new Dictionary();
+
+ Expression *ufilter = ConfigCompiler::CompileText("<API query>", filter);
Dictionary::Ptr filter_vars = query->Get("filter_vars");
if (filter_vars) {
ObjectLock olock(filter_vars);
BOOST_FOREACH(const Dictionary::Pair& kv, filter_vars) {
- frame.Locals->Set(kv.first, kv.second);
+ uvars->Set(kv.first, kv.second);
}
}
+ frame.Self = uvars;
+
try {
- provider->FindTargets(type, boost::bind(&FilteredAddTarget, boost::ref(frame), ufilter, boost::ref(result), _1));
+ provider->FindTargets(type, boost::bind(&FilteredAddTarget,
+ boost::ref(permissionFrame), permissionFilter,
+ boost::ref(frame), ufilter, boost::ref(result), _1));
} catch (const std::exception& ex) {
delete ufilter;
throw;
#define FILTERUTILITY_H
#include "remote/i2-remote.hpp"
+#include "remote/apiuser.hpp"
+#include "config/expression.hpp"
#include "base/dictionary.hpp"
#include "base/configobject.hpp"
#include <set>
{
std::set<String> Types;
TargetProvider::Ptr Provider;
+ String Permission;
};
/**
{
public:
static Type::Ptr TypeFromPluralName(const String& pluralName);
- static std::vector<Value> GetFilterTargets(const QueryDescription& qd, const Dictionary::Ptr& query);
+ static void CheckPermission(const ApiUser::Ptr& user, const String& permission, Expression **filter = NULL);
+ static std::vector<Value> GetFilterTargets(const QueryDescription& qd, const Dictionary::Ptr& query, const ApiUser::Ptr& user);
};
}
else {
user = ApiUser::GetByName(username);
- if (!user || !user->CheckPassword(password))
+ if (user && user->GetPassword() != password)
user.reset();
}
params->Set(attr, request.RequestUrl->GetPath()[3]);
}
- std::vector<Value> objs = FilterUtility::GetFilterTargets(qd, params);
+ std::vector<Value> objs = FilterUtility::GetFilterTargets(qd, params, user);
Dictionary::Ptr attrs = params->Get("attrs");
QueryDescription qd;
qd.Types.insert(type->GetName());
+ qd.Permission = "objects/query/" + type->GetName();
std::vector<String> joinAttrs;
joinAttrs.push_back("");
params->Set(attr, request.RequestUrl->GetPath()[3]);
}
- std::vector<Value> objs = FilterUtility::GetFilterTargets(qd, params);
+ std::vector<Value> objs = FilterUtility::GetFilterTargets(qd, params, user);
Array::Ptr results = new Array();
#include "remote/statushandler.hpp"
#include "remote/httputility.hpp"
+#include "remote/filterutility.hpp"
#include "base/serializer.hpp"
#include "base/statsfunction.hpp"
REGISTER_URLHANDLER("/v1/status", StatusHandler);
+class StatusTargetProvider : public TargetProvider
+{
+public:
+ DECLARE_PTR_TYPEDEFS(StatusTargetProvider);
+
+ virtual void FindTargets(const String& type,
+ const boost::function<void (const Value&)>& addTarget) const override
+ {
+ typedef std::pair<String, StatsFunction::Ptr> kv_pair;
+ BOOST_FOREACH(const kv_pair& kv, StatsFunctionRegistry::GetInstance()->GetItems()) {
+ addTarget(GetTargetByName("Status", kv.first));
+ }
+ }
+
+ virtual Value GetTargetByName(const String& type, const String& name) const override
+ {
+ StatsFunction::Ptr func = StatsFunctionRegistry::GetInstance()->GetItem(name);
+
+ Dictionary::Ptr result = new Dictionary();
+
+ Dictionary::Ptr status = new Dictionary();
+ Array::Ptr perfdata = new Array();
+ func->Invoke(status, perfdata);
+
+ result->Set("name", name);
+ result->Set("status", status);
+ result->Set("perfdata", perfdata);
+
+ return result;
+ }
+
+ virtual bool IsValidType(const String& type) const override
+ {
+ return type == "Status";
+ }
+
+ virtual String GetPluralName(const String& type) const override
+ {
+ return "statuses";
+ }
+};
+
bool StatusHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
Dictionary::Ptr result = new Dictionary();
return true;
}
- if (request.RequestUrl->GetPath().size() < 2) {
- response.SetStatus(400, "Bad request");
- HttpUtility::SendJsonBody(response, result);
- return true;
- }
-
- Array::Ptr results = new Array();
- Dictionary::Ptr resultInner = new Dictionary();
- if (request.RequestUrl->GetPath().size() > 2) {
+ QueryDescription qd;
+ qd.Types.insert("Status");
+ qd.Provider = new StatusTargetProvider();
+ qd.Permission = "status/query";
- StatsFunction::Ptr funcptr = StatsFunctionRegistry::GetInstance()->GetItem(request.RequestUrl->GetPath()[2]);
- resultInner = new Dictionary();
+ Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);
- if (!funcptr)
- return false;
+ params->Set("type", "Status");
- results->Add(resultInner);
+ if (request.RequestUrl->GetPath().size() >= 3)
+ params->Set("name", request.RequestUrl->GetPath()[2]);
- Dictionary::Ptr status = new Dictionary();
- Array::Ptr perfdata = new Array();
- funcptr->Invoke(status, perfdata);
-
- resultInner->Set("status", status);
- resultInner->Set("perfdata", perfdata);
- } else {
- typedef std::pair<String, StatsFunction::Ptr> kv_pair;
- BOOST_FOREACH(const kv_pair& kv, StatsFunctionRegistry::GetInstance()->GetItems()) {
- resultInner = new Dictionary();
- Dictionary::Ptr funcStatus = new Dictionary();
- Array::Ptr funcPData = new Array();
- kv.second->Invoke(funcStatus, funcPData);
-
- resultInner->Set("name", kv.first);
- resultInner->Set("status", funcPData);
- resultInner->Set("perfdata", funcPData);
+ std::vector<Value> objs = FilterUtility::GetFilterTargets(qd, params, user);
- results->Add(resultInner);
- }
- }
+ Array::Ptr results = Array::FromVector(objs);
result->Set("results", results);
bool TypeQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
- if (request.RequestMethod != "GET")
- return false;
+ Dictionary::Ptr result = new Dictionary();
- if (request.RequestUrl->GetPath().size() < 2)
- return false;
+ if (request.RequestMethod != "GET") {
+ response.SetStatus(400, "Bad request");
+ result->Set("info", "Request must be type GET");
+ HttpUtility::SendJsonBody(response, result);
+ return true;
+ }
QueryDescription qd;
qd.Types.insert("Type");
if (request.RequestUrl->GetPath().size() >= 3)
params->Set("name", request.RequestUrl->GetPath()[2]);
- std::vector<Value> objs = FilterUtility::GetFilterTargets(qd, params);
+ std::vector<Value> objs = FilterUtility::GetFilterTargets(qd, params, user);
Array::Ptr results = new Array();
}
}
- Dictionary::Ptr result = new Dictionary();
result->Set("results", results);
response.SetStatus(200, "OK");
base-stream.cpp base-string.cpp base-timer.cpp base-type.cpp
base-value.cpp config-ops.cpp icinga-macros.cpp
icinga-perfdata.cpp test.cpp
- remote-url.cpp remote-apiuser.cpp
+ remote-url.cpp
)
set(livestatus_test_SOURCES
icinga_perfdata/ignore_invalid_warn_crit_min_max
icinga_perfdata/invalid
icinga_perfdata/multi
- remote_apiuser/get_password
- remote_apiuser/check_password
remote_url/id_and_path
remote_url/parameters
remote_url/get_and_set
+++ /dev/null
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#include "remote/apiuser.hpp"
-#include <boost/test/unit_test.hpp>
-
-using namespace icinga;
-
-BOOST_AUTO_TEST_SUITE(remote_apiuser)
-
-BOOST_AUTO_TEST_CASE(construct)
-{
- ApiUser::Ptr apiuser = new ApiUser();
- BOOST_CHECK(apiuser);
-}
-
-BOOST_AUTO_TEST_CASE(get_password)
-{
- ApiUser::Ptr apiuser = new ApiUser();
- apiuser->SetPassword("icingar0xx");
-
- BOOST_CHECK(apiuser->GetPassword() == "*****");
-}
-
-BOOST_AUTO_TEST_CASE(check_password)
-{
- ApiUser::Ptr apiuser = new ApiUser();
- apiuser->SetPassword("icingar0xx");
-
- BOOST_CHECK(apiuser->CheckPassword("1cing4r0xx") == false);
- BOOST_CHECK(apiuser->CheckPassword("icingar0xx") == true);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
else
m_Impl << "\t\t" << "const Dictionary::Ptr& dict = value;" << std::endl;
- m_Impl << (type_check ? "\t" : "") << "\t\t" << "ObjectLock olock(dict);" << std::endl
- << (type_check ? "\t" : "") << "\t\t" << "BOOST_FOREACH(const Dictionary::Pair& kv, dict) {" << std::endl
- << (type_check ? "\t" : "") << "\t\t\t" << "const String& akey = kv.first;" << std::endl
- << (type_check ? "\t" : "") << "\t\t\t" << "const Value& avalue = kv.second;" << std::endl;
+ m_Impl << (type_check ? "\t" : "") << "\t\t" << "{" << std::endl
+ << (type_check ? "\t" : "") << "\t\t\t" << "ObjectLock olock(dict);" << std::endl
+ << (type_check ? "\t" : "") << "\t\t\t" << "BOOST_FOREACH(const Dictionary::Pair& kv, dict) {" << std::endl
+ << (type_check ? "\t" : "") << "\t\t\t\t" << "const String& akey = kv.first;" << std::endl
+ << (type_check ? "\t" : "") << "\t\t\t\t" << "const Value& avalue = kv.second;" << std::endl;
indent = true;
} else if (rule.Type == "Array") {
if (type_check)
m_Impl << "\t\t" << "const Array::Ptr& arr = value;" << std::endl;
m_Impl << (type_check ? "\t" : "") << "\t\t" << "Array::SizeType anum = 0;" << std::endl
- << (type_check ? "\t" : "") << "\t\t" << "ObjectLock olock(arr);" << std::endl
- << (type_check ? "\t" : "") << "\t\t" << "BOOST_FOREACH(const Value& avalue, arr) {" << std::endl
- << (type_check ? "\t" : "") << "\t\t\t" << "String akey = Convert::ToString(anum);" << std::endl;
+ << (type_check ? "\t" : "") << "\t\t" << "{" << std::endl
+ << (type_check ? "\t" : "") << "\t\t\t" << "ObjectLock olock(arr);" << std::endl
+ << (type_check ? "\t" : "") << "\t\t\t" << "BOOST_FOREACH(const Value& avalue, arr) {" << std::endl
+ << (type_check ? "\t" : "") << "\t\t\t\t" << "String akey = Convert::ToString(anum);" << std::endl;
indent = true;
} else {
m_Impl << (type_check ? "\t" : "") << "\t\t" << "String akey = \"\";" << std::endl
else
subvalidator_prefix = name;
- m_Impl << (type_check ? "\t" : "") << (indent ? "\t" : "") << "\t\t" << "location.push_back(akey);" << std::endl
- << (type_check ? "\t" : "") << (indent ? "\t" : "") << "\t\t" << "TIValidate" << subvalidator_prefix << "_" << i << "(object, akey, avalue, location, utils);" << std::endl
- << (type_check ? "\t" : "") << (indent ? "\t" : "") << "\t\t" << "location.pop_back();" << std::endl;
+ m_Impl << (type_check ? "\t" : "") << (indent ? "\t\t" : "") << "\t\t" << "location.push_back(akey);" << std::endl
+ << (type_check ? "\t" : "") << (indent ? "\t\t" : "") << "\t\t" << "TIValidate" << subvalidator_prefix << "_" << i << "(object, akey, avalue, location, utils);" << std::endl
+ << (type_check ? "\t" : "") << (indent ? "\t\t" : "") << "\t\t" << "location.pop_back();" << std::endl;
if (rule.Type == "Array")
- m_Impl << (type_check ? "\t" : "") << "\t\t\t" << "anum++;" << std::endl;
+ m_Impl << (type_check ? "\t" : "") << "\t\t\t\t" << "anum++;" << std::endl;
- if (rule.Type == "Dictionary" || rule.Type == "Array")
- m_Impl << (type_check ? "\t" : "") << "\t\t" << "}" << std::endl;
+ if (rule.Type == "Dictionary" || rule.Type == "Array") {
+ m_Impl << (type_check ? "\t" : "") << "\t\t\t" << "}" << std::endl
+ << (type_check ? "\t" : "") << "\t\t" << "}" << std::endl;
+ }
for (std::vector<Rule>::size_type i = 0; i < rule.Rules.size(); i++) {
const Rule& srule = rule.Rules[i];
continue;
if (rule.Type == "Dictionary") {
- m_Impl << (type_check ? "\t" : "") << "\t\t" << "if (dict.Get(\"" << srule.Pattern << "\").IsEmpty())" << std::endl
- << (type_check ? "\t" : "") << "\t\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(dynamic_cast<ConfigObject *>(this), location, \"Required dictionary item '" << srule.Pattern << "' is not set.\"));" << std::endl;
+ m_Impl << (type_check ? "\t" : "") << "\t\t" << "if (dict->Get(\"" << srule.Pattern << "\").IsEmpty())" << std::endl
+ << (type_check ? "\t" : "") << "\t\t\t" << "BOOST_THROW_EXCEPTION(ValidationError(dynamic_pointer_cast<ConfigObject>(object), location, \"Required dictionary item '" << srule.Pattern << "' is not set.\"));" << std::endl;
} else if (rule.Type == "Array") {
int index = -1;
std::stringstream idxbuf;