Пример #1
0
	static inline Value ConstructorCall(const Type::Ptr& type, const std::vector<Value>& args, const DebugInfo& debugInfo = DebugInfo())
	{
		if (type->GetName() == "String") {
			if (args.empty())
				return "";
			else if (args.size() == 1)
				return Convert::ToString(args[0]);
			else
				BOOST_THROW_EXCEPTION(ScriptError("Too many arguments for constructor."));
		} else if (type->GetName() == "Number") {
			if (args.empty())
				return 0;
			else if (args.size() == 1)
				return Convert::ToDouble(args[0]);
			else
				BOOST_THROW_EXCEPTION(ScriptError("Too many arguments for constructor."));
		} else if (type->GetName() == "Boolean") {
			if (args.empty())
				return 0;
			else if (args.size() == 1)
				return Convert::ToBool(args[0]);
			else
				BOOST_THROW_EXCEPTION(ScriptError("Too many arguments for constructor."));
		} else if (args.size() == 1 && type->IsAssignableFrom(args[0].GetReflectionType()))
			return args[0];
		else
			return type->Instantiate(args);
	}
Пример #2
0
bool ObjectQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
	if (request.RequestUrl->GetPath().size() < 3 || request.RequestUrl->GetPath().size() > 4)
		return false;

	if (request.RequestMethod != "GET")
		return false;

	Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[2]);

	if (!type) {
		HttpUtility::SendJsonError(response, 400, "Invalid type specified.");
		return true;
	}

	QueryDescription qd;
	qd.Types.insert(type->GetName());
	qd.Permission = "objects/query/" + type->GetName();

	std::vector<String> joinAttrs;
	joinAttrs.push_back("");

	for (int fid = 0; fid < type->GetFieldCount(); fid++) {
		Field field = type->GetFieldInfo(fid);

		if (field.Attributes & FANavigation)
			joinAttrs.push_back(field.Name);
	}

	Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);

	params->Set("type", type->GetName());

	if (request.RequestUrl->GetPath().size() >= 4) {
		String attr = type->GetName();
		boost::algorithm::to_lower(attr);
		params->Set(attr, request.RequestUrl->GetPath()[3]);
	}

	std::vector<Value> objs = FilterUtility::GetFilterTargets(qd, params, user);

	Array::Ptr results = new Array();

	std::set<String> attrs;
	Array::Ptr uattrs = params->Get("attrs");

	if (uattrs) {
		ObjectLock olock(uattrs);
		BOOST_FOREACH(const String& uattr, uattrs) {
			attrs.insert(uattr);
		}
	}
Пример #3
0
	static inline Value CopyConstructorCall(const Type::Ptr& type, const Value& value, const DebugInfo& debugInfo = DebugInfo())
	{
		if (type->GetName() == "String")
			return Convert::ToString(value);
		else if (type->GetName() == "Number")
			return Convert::ToDouble(value);
		else if (type->GetName() == "Boolean")
			return Convert::ToBool(value);
		else if (!type->IsAssignableFrom(value.GetReflectionType()))
			BOOST_THROW_EXCEPTION(ScriptError("Invalid cast: Tried to cast object of type '" + value.GetReflectionType()->GetName() + "' to type '" + type->GetName() + "'", debugInfo));
		else
			return value;
	}
Пример #4
0
bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& fullName,
    const Array::Ptr& templates, const Dictionary::Ptr& attrs, const Array::Ptr& errors)
{
	NameComposer *nc = dynamic_cast<NameComposer *>(type.get());
	Dictionary::Ptr nameParts;
	String name;

	if (nc) {
		nameParts = nc->ParseName(fullName);
		name = nameParts->Get("name");
	} else
		name = fullName;

	ConfigItemBuilder::Ptr builder = new ConfigItemBuilder();
	builder->SetType(type->GetName());
	builder->SetName(name);
	builder->SetScope(ScriptGlobal::GetGlobals());
	builder->SetPackage("_api");

	if (templates) {
		ObjectLock olock(templates);
		BOOST_FOREACH(const String& tmpl, templates) {
			ImportExpression *expr = new ImportExpression(MakeLiteral(tmpl));
			builder->AddExpression(expr);
		}
	}
Пример #5
0
String Value::GetTypeName(void) const
{
	Type::Ptr t;

	switch (GetType()) {
		case ValueEmpty:
			return "Empty";
		case ValueNumber:
			return "Number";
		case ValueBoolean:
			return "Boolean";
		case ValueString:
			return "String";
		case ValueObject:
			t = boost::get<Object::Ptr>(m_Value)->GetReflectionType();
			if (!t) {
				if (IsObjectType<Array>())
					return "Array";
				else if (IsObjectType<Dictionary>())
					return "Dictionary";
				else
					return "Object";
			} else
				return t->GetName();
		default:
			return "Invalid";
	}
}
Пример #6
0
	static inline Value ConstructorCall(const Type::Ptr& type, const DebugInfo& debugInfo = DebugInfo())
	{
		if (type->GetName() == "String")
			return "";
		else if (type->GetName() == "Number")
			return 0;
		else if (type->GetName() == "Boolean")
			return false;
		else {
			Object::Ptr object = type->Instantiate();

			if (!object)
				BOOST_THROW_EXCEPTION(ScriptError("Failed to instantiate object of type '" + type->GetName() + "'", debugInfo));

			return object;
		}
	}
Пример #7
0
bool ConfigObjectUtility::DeleteObjectHelper(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors)
{
	std::vector<Object::Ptr> parents = DependencyGraph::GetParents(object);

	Type::Ptr type = object->GetReflectionType();

	if (!parents.empty() && !cascade) {
		if (errors)
			errors->Add("Object '" + object->GetName() + "' of type '" + type->GetName() +
			    "' cannot be deleted because other objects depend on it. "
			    "Use cascading delete to delete it anyway.");

		return false;
	}

	for (const Object::Ptr& pobj : parents) {
		ConfigObject::Ptr parentObj = dynamic_pointer_cast<ConfigObject>(pobj);

		if (!parentObj)
			continue;

		DeleteObjectHelper(parentObj, cascade, errors);
	}

	ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type, object->GetName());

	try {
		/* mark this object for cluster delete event */
		object->SetExtension("ConfigObjectDeleted", true);
		/* triggers signal for DB IDO and other interfaces */
		object->Deactivate(true);

		if (item)
			item->Unregister();
		else
			object->Unregister();

	} catch (const std::exception& ex) {
		if (errors)
			errors->Add(DiagnosticInformation(ex));

		return false;
	}

	String path = GetObjectConfigPath(object->GetReflectionType(), object->GetName());

	if (Utility::PathExists(path)) {
		if (unlink(path.CStr()) < 0 && errno != ENOENT) {
			BOOST_THROW_EXCEPTION(posix_error()
			    << boost::errinfo_api_function("unlink")
			    << boost::errinfo_errno(errno)
			    << boost::errinfo_file_name(path));
		}
	}

	return true;
}
Пример #8
0
bool StatusQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
	if (request.RequestMethod != "GET")
		return false;

	if (request.RequestUrl->GetPath().size() < 2)
		return false;

	Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[1]);

	if (!type)
		return false;

	QueryDescription qd;
	qd.Types.insert(type);

	std::vector<String> joinTypes;
	joinTypes.push_back(type->GetName());

	Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);

	params->Set("type", type->GetName());

	if (request.RequestUrl->GetPath().size() >= 3) {
		String attr = type->GetName();
		boost::algorithm::to_lower(attr);
		params->Set(attr, request.RequestUrl->GetPath()[2]);
	}

	std::vector<ConfigObject::Ptr> objs = FilterUtility::GetFilterTargets(qd, params);

	Array::Ptr results = new Array();

	std::set<String> attrs;
	Array::Ptr uattrs = params->Get("attrs");

	if (uattrs) {
		ObjectLock olock(uattrs);
		BOOST_FOREACH(const String& uattr, uattrs) {
			attrs.insert(uattr);
		}
	}
Пример #9
0
String ConfigObjectUtility::CreateObjectConfig(const Type::Ptr& type, const String& fullName,
    bool ignoreOnError, const Array::Ptr& templates, const Dictionary::Ptr& attrs)
{
	NameComposer *nc = dynamic_cast<NameComposer *>(type.get());
	Dictionary::Ptr nameParts;
	String name;

	if (nc) {
		nameParts = nc->ParseName(fullName);
		name = nameParts->Get("name");
	} else
		name = fullName;

	Dictionary::Ptr allAttrs = new Dictionary();

	if (attrs) {
		attrs->CopyTo(allAttrs);

		ObjectLock olock(attrs);
		for (const Dictionary::Pair& kv : attrs) {
			int fid = type->GetFieldId(kv.first.SubStr(0, kv.first.FindFirstOf(".")));

			if (fid < 0)
				BOOST_THROW_EXCEPTION(ScriptError("Invalid attribute specified: " + kv.first));

			Field field = type->GetFieldInfo(fid);

			if (!(field.Attributes & FAConfig) || kv.first == "name")
				BOOST_THROW_EXCEPTION(ScriptError("Attribute is marked for internal use only and may not be set: " + kv.first));
		}
	}

	if (nameParts)
		nameParts->CopyTo(allAttrs);

	allAttrs->Remove("name");

	/* update the version for config sync */
	allAttrs->Set("version", Utility::GetTime());

	std::ostringstream config;
	ConfigWriter::EmitConfigItem(config, type->GetName(), name, false, ignoreOnError, templates, allAttrs);
	ConfigWriter::EmitRaw(config, "\n");

	return config.str();
}
Пример #10
0
bool FilterUtility::EvaluateFilter(ScriptFrame& frame, Expression *filter,
	const Object::Ptr& target, const String& variableName)
{
	if (!filter)
		return true;

	Type::Ptr type = target->GetReflectionType();
	String varName;

	if (variableName.IsEmpty())
		varName = type->GetName().ToLower();
	else
		varName = variableName;

	Namespace::Ptr frameNS;

	if (frame.Self.IsEmpty()) {
		frameNS = new Namespace();
		frame.Self = frameNS;
	} else {
		/* Enforce a namespace object for 'frame.self'. */
		ASSERT(frame.Self.IsObjectType<Namespace>());

		frameNS = frame.Self;
	}

	frameNS->Set("obj", target);
	frameNS->Set(varName, target);

	for (int fid = 0; fid < type->GetFieldCount(); fid++) {
		Field field = type->GetFieldInfo(fid);

		if ((field.Attributes & FANavigation) == 0)
			continue;

		Object::Ptr joinedObj = target->NavigateField(fid);

		if (field.NavigationName)
			frameNS->Set(field.NavigationName, joinedObj);
		else
			frameNS->Set(field.Name, joinedObj);
	}

	return Convert::ToBool(filter->Evaluate(frame));
}
Пример #11
0
Value icinga::GetPrototypeField(const Value& context, const String& field, bool not_found_error, const DebugInfo& debugInfo)
{
	Type::Ptr ctype = context.GetReflectionType();
	Type::Ptr type = ctype;

	do {
		Object::Ptr object = type->GetPrototype();

		if (object && object->HasOwnField(field))
			return object->GetFieldByName(field, false, debugInfo);

		type = type->GetBaseType();
	} while (type);

	if (not_found_error)
		BOOST_THROW_EXCEPTION(ScriptError("Invalid field access (for value of type '" + ctype->GetName() + "'): '" + field + "'", debugInfo));
	else
		return Empty;
}
Пример #12
0
ValidationError::ValidationError(const ConfigObject::Ptr& object, const std::vector<String>& attributePath, const String& message)
	: m_Object(object), m_AttributePath(attributePath), m_Message(message)
{
	String path;

	BOOST_FOREACH(const String& attribute, attributePath) {
		if (!path.IsEmpty())
			path += " -> ";

		path += "'" + attribute + "'";
	}

	Type::Ptr type = object->GetReflectionType();
	m_What = "Validation failed for object '" + object->GetName() + "' of type '" + type->GetName() + "'";

	if (!path.IsEmpty())
		m_What += "; Attribute " + path;

	m_What += ": " + message;
}
Пример #13
0
bool FilterUtility::EvaluateFilter(ScriptFrame& frame, Expression *filter,
    const Object::Ptr& target, const String& variableName)
{
	if (!filter)
		return true;

	Type::Ptr type = target->GetReflectionType();
	String varName;

	if (variableName.IsEmpty())
		varName = type->GetName().ToLower();
	else
		varName = variableName;

	Dictionary::Ptr vars;

	if (frame.Self.IsEmpty()) {
		vars = new Dictionary();
		frame.Self = vars;
	} else
		vars = frame.Self;

	vars->Set("obj", target);
	vars->Set(varName, target);

	for (int fid = 0; fid < type->GetFieldCount(); fid++) {
		Field field = type->GetFieldInfo(fid);

		if ((field.Attributes & FANavigation) == 0)
			continue;

		Object::Ptr joinedObj = target->NavigateField(fid);

		if (field.NavigationName)
			vars->Set(field.NavigationName, joinedObj);
		else
			vars->Set(field.Name, joinedObj);
	}

	return Convert::ToBool(filter->Evaluate(frame));
}
Пример #14
0
ConfigType::Ptr ConfigType::GetByName(const String& name)
{
	boost::mutex::scoped_lock lock(GetStaticMutex());

	ConfigType::TypeMap::const_iterator tt = InternalGetTypeMap().find(name);

	if (tt == InternalGetTypeMap().end()) {
		Type::Ptr type = Type::GetByName(name);

		if (!type || !ConfigObject::TypeInstance->IsAssignableFrom(type)
		    || type->IsAbstract())
			return ConfigType::Ptr();

		ConfigType::Ptr dtype = new ConfigType(name);

		InternalGetTypeMap()[type->GetName()] = dtype;
		InternalGetTypeVector().push_back(dtype);

		return dtype;
	}

	return tt->second;
}
Пример #15
0
bool ModifyObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
{
	if (request.RequestUrl->GetPath().size() < 3 || request.RequestUrl->GetPath().size() > 4)
		return false;

	if (request.RequestMethod != "POST")
		return false;

	Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[2]);

	if (!type) {
		HttpUtility::SendJsonError(response, 400, "Invalid type specified.");
		return true;
	}

	QueryDescription qd;
	qd.Types.insert(type->GetName());
	qd.Permission = "objects/modify/" + type->GetName();

	params->Set("type", type->GetName());

	if (request.RequestUrl->GetPath().size() >= 4) {
		String attr = type->GetName();
		boost::algorithm::to_lower(attr);
		params->Set(attr, request.RequestUrl->GetPath()[3]);
	}

	std::vector<Value> objs;

	try {
		objs = FilterUtility::GetFilterTargets(qd, params, user);
	} catch (const std::exception& ex) {
		HttpUtility::SendJsonError(response, 404,
		    "No objects found.",
		    HttpUtility::GetLastParameter(params, "verboseErrors") ? DiagnosticInformation(ex) : "");
		return true;
	}

	Dictionary::Ptr attrs = params->Get("attrs");

	Array::Ptr results = new Array();

	for (const ConfigObject::Ptr& obj : objs) {
		Dictionary::Ptr result1 = new Dictionary();

		result1->Set("type", type->GetName());
		result1->Set("name", obj->GetName());

		String key;

		try {
			if (attrs) {
				ObjectLock olock(attrs);
				for (const Dictionary::Pair& kv : attrs) {
					key = kv.first;
					obj->ModifyAttribute(kv.first, kv.second);
				}
			}

			result1->Set("code", 200);
			result1->Set("status", "Attributes updated.");
		} catch (const std::exception& ex) {
			result1->Set("code", 500);
			result1->Set("status", "Attribute '" + key + "' could not be set: " + DiagnosticInformation(ex));
		}

		results->Add(result1);
	}

	Dictionary::Ptr result = new Dictionary();
	result->Set("results", results);

	response.SetStatus(200, "OK");
	HttpUtility::SendJsonBody(response, result);

	return true;
}
Пример #16
0
bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& fullName,
	const String& config, const Array::Ptr& errors, const Array::Ptr& diagnosticInformation)
{
	{
		boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex());
		if (!ConfigPackageUtility::PackageExists("_api")) {
			ConfigPackageUtility::CreatePackage("_api");

			String stage = ConfigPackageUtility::CreateStage("_api");
			ConfigPackageUtility::ActivateStage("_api", stage);
		}
	}

	ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type, fullName);

	if (item) {
		errors->Add("Object '" + fullName + "' already exists.");
		return false;
	}

	String path = GetObjectConfigPath(type, fullName);
	Utility::MkDirP(Utility::DirName(path), 0700);

	if (Utility::PathExists(path)) {
		errors->Add("Cannot create object '" + fullName + "'. Configuration file '" + path + "' already exists.");
		return false;
	}

	std::ofstream fp(path.CStr(), std::ofstream::out | std::ostream::trunc);
	fp << config;
	fp.close();

	std::unique_ptr<Expression> expr = ConfigCompiler::CompileFile(path, String(), "_api");

	try {
		ActivationScope ascope;

		ScriptFrame frame(true);
		expr->Evaluate(frame);
		expr.reset();

		WorkQueue upq;
		upq.SetName("ConfigObjectUtility::CreateObject");

		std::vector<ConfigItem::Ptr> newItems;

		/* Disable logging for object creation, but do so ourselves later on. */
		if (!ConfigItem::CommitItems(ascope.GetContext(), upq, newItems, true) || !ConfigItem::ActivateItems(upq, newItems, true, true)) {
			if (errors) {
				if (unlink(path.CStr()) < 0 && errno != ENOENT) {
					BOOST_THROW_EXCEPTION(posix_error()
						<< boost::errinfo_api_function("unlink")
						<< boost::errinfo_errno(errno)
						<< boost::errinfo_file_name(path));
				}

				for (const boost::exception_ptr& ex : upq.GetExceptions()) {
					errors->Add(DiagnosticInformation(ex, false));

					if (diagnosticInformation)
						diagnosticInformation->Add(DiagnosticInformation(ex));
				}
			}

			return false;
		}

		ApiListener::UpdateObjectAuthority();

		Log(LogInformation, "ConfigObjectUtility")
			<< "Created and activated object '" << fullName << "' of type '" << type->GetName() << "'.";

	} catch (const std::exception& ex) {
		if (unlink(path.CStr()) < 0 && errno != ENOENT) {
			BOOST_THROW_EXCEPTION(posix_error()
				<< boost::errinfo_api_function("unlink")
				<< boost::errinfo_errno(errno)
				<< boost::errinfo_file_name(path));
		}

		if (errors)
			errors->Add(DiagnosticInformation(ex, false));

		if (diagnosticInformation)
			diagnosticInformation->Add(DiagnosticInformation(ex));

		return false;
	}

	return true;
}
Пример #17
0
bool ObjectQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
{
	if (request.RequestUrl->GetPath().size() < 3 || request.RequestUrl->GetPath().size() > 4)
		return false;

	if (request.RequestMethod != "GET")
		return false;

	Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[2]);

	if (!type) {
		HttpUtility::SendJsonError(response, params, 400, "Invalid type specified.");
		return true;
	}

	QueryDescription qd;
	qd.Types.insert(type->GetName());
	qd.Permission = "objects/query/" + type->GetName();

	Array::Ptr uattrs, ujoins, umetas;

	try {
		uattrs = params->Get("attrs");
	} catch (const std::exception&) {
		HttpUtility::SendJsonError(response, params, 400,
			"Invalid type for 'attrs' attribute specified. Array type is required.");
		return true;
	}

	try {
		ujoins = params->Get("joins");
	} catch (const std::exception&) {
		HttpUtility::SendJsonError(response, params, 400,
			"Invalid type for 'joins' attribute specified. Array type is required.");
		return true;
	}

	try {
		umetas = params->Get("meta");
	} catch (const std::exception&) {
		HttpUtility::SendJsonError(response, params, 400,
			"Invalid type for 'meta' attribute specified. Array type is required.");
		return true;
	}

	bool allJoins = HttpUtility::GetLastParameter(params, "all_joins");

	params->Set("type", type->GetName());

	if (request.RequestUrl->GetPath().size() >= 4) {
		String attr = type->GetName();
		boost::algorithm::to_lower(attr);
		params->Set(attr, request.RequestUrl->GetPath()[3]);
	}

	std::vector<Value> objs;

	try {
		objs = FilterUtility::GetFilterTargets(qd, params, user);
	} catch (const std::exception& ex) {
		HttpUtility::SendJsonError(response, params, 404,
			"No objects found.",
			DiagnosticInformation(ex));
		return true;
	}

	ArrayData results;
	results.reserve(objs.size());

	std::set<String> joinAttrs;
	std::set<String> userJoinAttrs;

	if (ujoins) {
		ObjectLock olock(ujoins);
		for (const String& ujoin : ujoins) {
			userJoinAttrs.insert(ujoin.SubStr(0, ujoin.FindFirstOf(".")));
		}
	}

	for (int fid = 0; fid < type->GetFieldCount(); fid++) {
		Field field = type->GetFieldInfo(fid);

		if (!(field.Attributes & FANavigation))
			continue;

		if (!allJoins && userJoinAttrs.find(field.NavigationName) == userJoinAttrs.end())
			continue;

		joinAttrs.insert(field.Name);
	}

	for (const ConfigObject::Ptr& obj : objs) {
		DictionaryData result1{
			{ "name", obj->GetName() },
			{ "type", obj->GetReflectionType()->GetName() }
		};

		DictionaryData metaAttrs;

		if (umetas) {
			ObjectLock olock(umetas);
			for (const String& meta : umetas) {
				if (meta == "used_by") {
					Array::Ptr used_by = new Array();
					metaAttrs.emplace_back("used_by", used_by);

					for (const Object::Ptr& pobj : DependencyGraph::GetParents((obj)))
					{
						ConfigObject::Ptr configObj = dynamic_pointer_cast<ConfigObject>(pobj);

						if (!configObj)
							continue;

						used_by->Add(new Dictionary({
							{ "type", configObj->GetReflectionType()->GetName() },
							{ "name", configObj->GetName() }
						}));
					}
				} else if (meta == "location") {
					metaAttrs.emplace_back("location", obj->GetSourceLocation());
				} else {
					HttpUtility::SendJsonError(response, params, 400, "Invalid field specified for meta: " + meta);
					return true;
				}
			}
		}

		result1.emplace_back("meta", new Dictionary(std::move(metaAttrs)));

		try {
			result1.emplace_back("attrs", SerializeObjectAttrs(obj, String(), uattrs, false, false));
		} catch (const ScriptError& ex) {
			HttpUtility::SendJsonError(response, params, 400, ex.what());
			return true;
		}

		DictionaryData joins;

		for (const String& joinAttr : joinAttrs) {
			Object::Ptr joinedObj;
			int fid = type->GetFieldId(joinAttr);

			if (fid < 0) {
				HttpUtility::SendJsonError(response, params, 400, "Invalid field specified for join: " + joinAttr);
				return true;
			}

			Field field = type->GetFieldInfo(fid);

			if (!(field.Attributes & FANavigation)) {
				HttpUtility::SendJsonError(response, params, 400, "Not a joinable field: " + joinAttr);
				return true;
			}

			joinedObj = obj->NavigateField(fid);

			if (!joinedObj)
				continue;

			String prefix = field.NavigationName;

			try {
				joins.emplace_back(prefix, SerializeObjectAttrs(joinedObj, prefix, ujoins, true, allJoins));
			} catch (const ScriptError& ex) {
				HttpUtility::SendJsonError(response, params, 400, ex.what());
				return true;
			}
		}

		result1.emplace_back("joins", new Dictionary(std::move(joins)));

		results.push_back(new Dictionary(std::move(result1)));
	}

	Dictionary::Ptr result = new Dictionary({
		{ "results", new Array(std::move(results)) }
	});

	response.SetStatus(200, "OK");
	HttpUtility::SendJsonBody(response, params, result);

	return true;
}
Пример #18
0
void Type::Register(const Type::Ptr& type)
{
	VERIFY(GetByName(type->GetName()) == NULL);

	ScriptGlobal::Set(type->GetName(), type);
}
bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
	if (request.RequestUrl->GetPath().size() != 4)
		return false;

	if (request.RequestMethod != "PUT")
		return false;

	Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[2]);

	if (!type) {
		HttpUtility::SendJsonError(response, 400, "Invalid type specified.");
		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");
	Dictionary::Ptr attrs = params->Get("attrs");

	Dictionary::Ptr result1 = new Dictionary();
	int code;
	String status;
	Array::Ptr errors = new Array();

	bool ignoreOnError = false;

	if (params->Contains("ignore_on_error"))
		ignoreOnError = HttpUtility::GetLastParameter(params, "ignore_on_error");

	String config = ConfigObjectUtility::CreateObjectConfig(type, name, ignoreOnError, templates, attrs);

	if (!ConfigObjectUtility::CreateObject(type, name, config, errors)) {
		result1->Set("errors", errors);
		HttpUtility::SendJsonError(response, 500, "Object could not be created.");
		return true;
	}

	ConfigType::Ptr dtype = ConfigType::GetByName(type->GetName());

	ConfigObject::Ptr obj = dtype->GetObject(name);

	result1->Set("code", 200);

	if (obj)
		result1->Set("status", "Object was created");
	else if (!obj && ignoreOnError)
		result1->Set("status", "Object was not created but 'ignore_on_error' was set to true");

	Array::Ptr results = new Array();
	results->Add(result1);

	Dictionary::Ptr result = new Dictionary();
	result->Set("results", results);

	response.SetStatus(200, "OK");
	HttpUtility::SendJsonBody(response, result);

	return true;
}
Пример #20
0
void Type::Register(const Type::Ptr& type)
{
	VERIFY(GetByName(type->GetName()) == NULL);

	GetTypes()[type->GetName()] = type;
}
Пример #21
0
Value Object::GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const
{
	Type::Ptr type = GetReflectionType();

	if (!type)
		return Empty;

	int fid = type->GetFieldId(field);

	if (fid == -1)
		return GetPrototypeField(const_cast<Object *>(this), field, true, debugInfo);

	if (sandboxed) {
		Field fieldInfo = type->GetFieldInfo(fid);

		if (fieldInfo.Attributes & FANoUserView)
			BOOST_THROW_EXCEPTION(ScriptError("Accessing the field '" + field + "' for type '" + type->GetName() + "' is not allowed in sandbox mode.", debugInfo));
	}

	return GetField(fid);
}
Пример #22
0
void Object::SetFieldByName(const String& field, const Value& value, const DebugInfo& debugInfo)
{
	Type::Ptr type = GetReflectionType();

	if (!type)
		BOOST_THROW_EXCEPTION(ScriptError("Cannot set field on object.", debugInfo));

	int fid = type->GetFieldId(field);

	if (fid == -1)
		BOOST_THROW_EXCEPTION(ScriptError("Attribute '" + field + "' does not exist.", debugInfo));

	try {
		SetField(fid, value);
	} catch (const boost::bad_lexical_cast&) {
		Field fieldInfo = type->GetFieldInfo(fid);
		Type::Ptr ftype = Type::GetByName(fieldInfo.TypeName);
		BOOST_THROW_EXCEPTION(ScriptError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "', expected '" + ftype->GetName() + "'", debugInfo));
	} catch (const std::bad_cast&) {
		Field fieldInfo = type->GetFieldInfo(fid);
		Type::Ptr ftype = Type::GetByName(fieldInfo.TypeName);
		BOOST_THROW_EXCEPTION(ScriptError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "', expected '" + ftype->GetName() + "'", debugInfo));
	}
}