From a6a8a4c16684fbcb05b36aaa5e4b52d8f36b0eea Mon Sep 17 00:00:00 2001 From: Ratan Gupta Date: Mon, 7 Aug 2017 08:18:44 +0530 Subject: Convert value to expected type during POST method This fix converts the values passed as the method arguments to the expected type during REST POST method Invalid args exception handling. if Invalid args exception occurs,this commit does the following set of operations. =>Get the method signature. =>Convert the value to the expected type. =>re-execute the post method. Resolves openbmc/openbmc#1889 Change-Id: I3fe9feda40187e4b72adf800b6bc4eb46f05a27c Signed-off-by: Ratan Gupta --- module/obmc/wsgi/apps/rest_dbus.py | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'module/obmc/wsgi/apps') diff --git a/module/obmc/wsgi/apps/rest_dbus.py b/module/obmc/wsgi/apps/rest_dbus.py index 41538bc..5719236 100644 --- a/module/obmc/wsgi/apps/rest_dbus.py +++ b/module/obmc/wsgi/apps/rest_dbus.py @@ -63,6 +63,22 @@ def get_type_signature_by_introspection(bus, service, object_path, return type_signature +def get_method_signature(bus, service, object_path, interface, method): + obj = bus.get_object(service, object_path) + iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable') + xml_string = iface.Introspect() + arglist = [] + + root = ElementTree.fromstring(xml_string) + for dbus_intf in root.findall('interface'): + if (dbus_intf.get('name') == interface): + for dbus_method in dbus_intf.findall('method'): + if(dbus_method.get('name') == method): + for arg in dbus_method.findall('arg'): + arglist.append(arg.get('type')) + return arglist + + def split_struct_signature(signature): struct_regex = r'(b|y|n|i|x|q|u|t|d|s|a\(.+?\)|\(.+?\))|a\{.+?\}+?' struct_matches = re.findall(struct_regex, signature) @@ -299,6 +315,8 @@ class MethodHandler(RouteHandler): def __init__(self, app, bus): super(MethodHandler, self).__init__( app, bus, self.verbs, self.rules, self.content_type) + self.service = '' + self.interface = '' def find(self, path, method): busses = self.try_mapper_call( @@ -321,8 +339,29 @@ class MethodHandler(RouteHandler): return request.route_data['method']() except dbus.exceptions.DBusException, e: + paramlist = [] if e.get_dbus_name() == DBUS_INVALID_ARGS: + + signature_list = get_method_signature(self.bus, self.service, + path, self.interface, + method) + if not signature_list: + abort(400, "Failed to get method signature: %s" % str(e)) + if len(signature_list) != len(request.parameter_list): + abort(400, "Invalid number of args") + converted_value = None + try: + for index, expected_type in enumerate(signature_list): + value = request.parameter_list[index] + converted_value = convert_type(expected_type, value) + paramlist.append(converted_value) + request.parameter_list = paramlist + self.do_post(path, method) + return + except Exception as ex: + abort(400, "Failed to convert the types") abort(400, str(e)) + if e.get_dbus_name() == DBUS_TYPE_ERROR: abort(400, str(e)) raise @@ -348,6 +387,8 @@ class MethodHandler(RouteHandler): m = self.find_method_in_interface( method, obj, x, y.get('method')) if m: + self.service = bus + self.interface = x return m -- cgit v1.2.1