diff roundup/rest.py @ 5562:70df783c4c0b REST-rebased

Cleanup, fixed a bug with delete action Change the returned type of every action from JSON to list/object committer: Ralf Schlatterbeck <rsc@runtux.com>
author Chau Nguyen <dangchau1991@yahoo.com>
date Wed, 30 Jan 2019 10:26:33 +0100
parents 7aa7f779198b
children 9a1614ff752d
line wrap: on
line diff
--- a/roundup/rest.py	Wed Jan 30 10:26:33 2019 +0100
+++ b/roundup/rest.py	Wed Jan 30 10:26:33 2019 +0100
@@ -8,7 +8,7 @@
 import json
 import pprint
 from roundup import hyperdb
-from roundup.cgi.templating import Unauthorised
+from roundup.exceptions import *
 from roundup import xmlrpc
 
 
@@ -21,18 +21,23 @@
         self.db = db
 
     def get_collection(self, class_name, input):
+        if not self.db.security.hasPermission('View', self.db.getuid(),
+                                              class_name):
+            raise Unauthorised('Permission to view %s denied' % class_name)
         class_obj = self.db.getclass(class_name)
         prop_name = class_obj.labelprop()
         result = [{'id': item_id, 'name': class_obj.get(item_id, prop_name)}
                   for item_id in class_obj.list()
                   if self.db.security.hasPermission('View', self.db.getuid(),
-                                                    class_name, None, item_id)
-                  ]
-        result = json.JSONEncoder().encode(result)
-
+                                                    class_name,
+                                                    itemid=item_id)]
         return result
 
     def get_element(self, class_name, item_id, input):
+        if not self.db.security.hasPermission('View', self.db.getuid(),
+                                              class_name, itemid=item_id):
+            raise Unauthorised('Permission to view %s item %d denied' %
+                               (class_name, item_id))
         class_obj = self.db.getclass(class_name)
         props = class_obj.properties.keys()
         props.sort()  # sort properties
@@ -40,9 +45,8 @@
                   for prop_name in props
                   if self.db.security.hasPermission('View', self.db.getuid(),
                                                     class_name, prop_name,
-                                                    item_id)
-                  ]
-        result = json.JSONEncoder().encode(dict(result))
+                                                    item_id)]
+        result = dict(result)
 
         return result
 
@@ -54,12 +58,13 @@
         class_obj = self.db.getclass(class_name)
 
         # convert types
-        props = xmlrpc.props_from_args(self.db, class_obj, input)
+        input_data = ["%s=%s" % (item.name, item.value) for item in input.value]
+        props = xmlrpc.props_from_args(self.db, class_obj, input_data)
 
         # check for the key property
         key = class_obj.getkey()
         if key and key not in props:
-            raise xmlrpc.UsageError, 'Must provide the "%s" property.' % key
+            raise UsageError('Must provide the "%s" property.' % key)
 
         for key in props:
             if not self.db.security.hasPermission('Create', self.db.getuid(),
@@ -69,10 +74,12 @@
 
         # do the actual create
         try:
-            result = class_obj.create(**props)
+            item_id = class_obj.create(**props)
             self.db.commit()
         except (TypeError, IndexError, ValueError), message:
-            raise xmlrpc.UsageError, message
+            raise UsageError(message)
+
+        result = {id: item_id}
         return result
 
     def post_element(self, class_name, item_id, input):
@@ -89,13 +96,15 @@
         raise NotImplementedError
 
     def delete_element(self, class_name, item_id, input):
-        # TODO: BUG with DELETE without form data. Working with random data
-        #       crash at line self.form = cgi.FieldStorage(fp=request.rfile, environ=env)
-        try:
-            self.db.destroynode(class_name, item_id)
-            result = 'OK'
-        except IndexError:
-            result = 'Error'
+        if not self.db.security.hasPermission('Delete', self.db.getuid(),
+                                              class_name, itemid=item_id):
+            raise Unauthorised('Permission to delete %s %s denied' %
+                               (class_name, item_id))
+        if item_id != input['id'].value:
+            raise UsageError('Must provide id key as confirmation')
+        self.db.destroynode(class_name, item_id)
+        self.db.commit()
+        result = {"status": "ok"}
 
         return result
 
@@ -106,33 +115,26 @@
         raise NotImplementedError
 
     def dispatch(self, method, uri, input):
-        print "METHOD: " + method + " URI: " + uri
-        print type(input)
-        pprint.pprint(input)
-        # TODO: process input_form directly instead of making a new array
-        # TODO: rest server
-        # TODO: check roundup/actions.py
-        # TODO: if uri_path has more than 2 child, return 404
-        # TODO: custom JSONEncoder to handle other data type
-        # TODO: catch all error and display error.
-
         # PATH is split to multiple pieces
         # 0 - rest
         # 1 - resource
+        resource_uri = uri.split("/")[1]
 
-        resource_uri = uri.split("/")[1]
-        input_data = ["%s=%s" % (item.name, item.value) for item in input]
-
+        output = None
         try:
             if resource_uri in self.db.classes:
-                output = getattr(self, "%s_collection" % method.lower())(resource_uri, input_data)
+                output = getattr(self, "%s_collection" % method.lower())(
+                    resource_uri, input)
             else:
                 class_name, item_id = hyperdb.splitDesignator(resource_uri)
-                output = getattr(self, "%s_element" % method.lower())(class_name, item_id, input_data)
+                output = getattr(self, "%s_element" % method.lower())(
+                    class_name, item_id, input)
         except hyperdb.DesignatorError:
-            pass  # invalid URI
+            raise NotImplementedError('Invalid URI')
         except AttributeError:
-            raise NotImplementedError  # Error: method is invalid
+            raise NotImplementedError('Method is invalid')
+        finally:
+            output = json.JSONEncoder().encode(output)
 
         print "Length: %s - Content(50 char): %s" % (len(output), output[:50])
         return output

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