diff roundup/rest.py @ 5659:1e51a709431c

Make Searching work in REST API Previously only Links/Multilinks where the property name (e.g. "status) is equal to the linked class name (e.g. "status") worked. Now we can search for String, Date, Link/Multilink, with no restrictions. Also honor the search permissions. In the process we rename page_size, page_index parameters to the search to @page_size and @page_index, respectively. Also renamed to add a leading '@' was the fields parameter to data/<classname>/<id> (it is now called @fields), and the action_name and action_args parameters to the PATCH method on data/<classname>/<id>.
author Ralf Schlatterbeck <rsc@runtux.com>
date Fri, 22 Mar 2019 09:56:10 +0100
parents 3401daf8613b
children d8d2b7724292
line wrap: on
line diff
--- a/roundup/rest.py	Thu Mar 21 11:23:09 2019 +0100
+++ b/roundup/rest.py	Fri Mar 22 09:56:10 2019 +0100
@@ -493,20 +493,34 @@
             'size': None,
             'index': 1   # setting just size starts at page 1
         }
+        uid = self.db.getuid()
         for form_field in input.value:
             key = form_field.name
             value = form_field.value
-            if key.startswith("where_"):  # serve the filter purpose
+            if key.startswith("@page_"):  # serve the paging purpose
                 key = key[6:]
-                filter_props[key] = [
-                    getattr(self.db, key).lookup(p)
-                    for p in value.split(",")
-                ]
-            elif key.startswith("page_"):  # serve the paging purpose
-                key = key[5:]
                 value = int(value)
                 page[key] = value
-
+            else: # serve the filter purpose
+                prop = class_obj.getprops()[key]
+                # We drop properties without search permission silently
+                # This reflects the current behavior of other roundup
+                # interfaces
+                if not self.db.security.hasSearchPermission(
+                    uid, class_name, key
+                ):
+                    continue
+                if isinstance (prop, (hyperdb.Link, hyperdb.Multilink)):
+                    vals = []
+                    linkcls = self.db.getclass (prop.classname)
+                    for p in value.split(","):
+                        if prop.try_id_parsing and p.isdigit():
+                            vals.append(p)
+                        else:
+                            vals.append(linkcls.lookup(p))
+                    filter_props[key] = vals
+                else:
+                    filter_props[key] = value
         if not filter_props:
             obj_list = class_obj.list()
         else:
@@ -542,11 +556,11 @@
                 result['@links'][rel] = []
                 result['@links'][rel].append({
                     'rel': rel,
-                    'uri': "%s/%s?page_index=%s&"%(self.data_path,
+                    'uri': "%s/%s?@page_index=%s&"%(self.data_path,
                                                    class_name,index) \
                        + '&'.join([ "%s=%s"%(field.name,field.value) \
                          for field in input.value \
-                           if field.name != "page_index"]) })
+                           if field.name != "@page_index"]) })
 
         result['@total_size'] = result_len
         self.client.setHeader("X-Count-Total", str(result_len))
@@ -590,7 +604,7 @@
         for form_field in input.value:
             key = form_field.name
             value = form_field.value
-            if key == "fields":
+            if key == "@fields":
                 props = value.split(",")
             if key == "@protected":
                 # allow client to request read only
@@ -1027,9 +1041,9 @@
             for form_field in input.value:
                 key = form_field.name
                 value = form_field.value
-                if key == "action_name":
+                if key == "@action_name":
                     name = value
-                elif key.startswith('action_args'):
+                elif key.startswith('@action_args'):
                     action_args.append(value)
 
             if name in self.actions:

Roundup Issue Tracker: http://roundup-tracker.org/