[Patchew-devel] [PATCH] Make Patchew cli use rest api

Shubham Jain shubhamjain7495 at gmail.com
Mon Jun 25 12:06:17 UTC 2018


- Disabled CSRF authentication until OAuth authentication, since DRF leads to csrf error while handling sessionauthentication.
- Added general rest_api function to make request to apis and get response.
- Make project functions use the rest_api_do instead of api_do
---
 api/rest.py |  9 +++++++-
 patchew-cli | 69 +++++++++++++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 61 insertions(+), 17 deletions(-)

diff --git a/api/rest.py b/api/rest.py
index 084dbbc..a584578 100644
--- a/api/rest.py
+++ b/api/rest.py
@@ -25,6 +25,12 @@ from rest_framework.response import Response
 import rest_framework
 from mbox import addr_db_to_rest, MboxMessage
 from rest_framework.parsers import JSONParser, BaseParser
+from rest_framework.authentication import SessionAuthentication
+
+class CsrfExemptSessionAuthentication(SessionAuthentication):
+
+    def enforce_csrf(self, request):
+        return  # To not perform the csrf check previously happening
 
 SEARCH_PARAM = 'q'
 
@@ -140,7 +146,8 @@ class ProjectsViewSet(viewsets.ModelViewSet):
     queryset = Project.objects.all().order_by('id')
     serializer_class = ProjectSerializer
     permission_classes = (PatchewPermission,)
-
+    authentication_classes = (CsrfExemptSessionAuthentication, )
+    
     @action(methods=['post'], detail=True, permission_classes=[ImportPermission])
     def update_project_head(self, request, pk=None):
         """
diff --git a/patchew-cli b/patchew-cli
index 174d1e6..cd5b3fa 100755
--- a/patchew-cli
+++ b/patchew-cli
@@ -61,7 +61,7 @@ class SubCommand(object):
     help = ""
     want_argv = False # Whether the command accepts extra arguments
 
-    def api_do(self, cmd, **data):
+    def api_do(self, cmd, **data):  
         """Do server api call"""
         logging.debug("API call '%s':" % cmd)
         logging.debug("data:\n%s" % data)
@@ -92,6 +92,39 @@ class SubCommand(object):
             r = None
         return r
 
+    def rest_api_do(self, url_cmd, request_method='get', content_type=None, **data):
+        cmd = url_cmd
+        logging.debug("API call '%s':" % url_cmd)
+        logging.debug("data:\n%s" % data)
+        cookie = http.cookiejar.MozillaCookieJar(COOKIE_FILENAME)
+        try:
+            cookie.load()
+        except IOError:
+            pass
+        except http.cookiejar.LoadError:
+            print("Error while loading cookie", COOKIE_FILENAME)
+            pass
+        handler = urllib.request.HTTPCookieProcessor(cookie)
+        opener = urllib.request.build_opener(handler)
+        url = self.base_url + '/api/v1/' + url_cmd + '/'
+        if data:
+            post_data = json.dumps(data)
+        else:
+            post_data = ""
+        req = urllib.request.Request(url, data=bytes(post_data, encoding="utf-8"))
+        if content_type is not None:
+            req.add_header('Content-Type', content_type)
+        req.get_method = lambda: request_method.upper()
+        resp = opener.open(req)
+        cookie.save(ignore_discard=True, ignore_expires=True)
+        respdata = resp.read()
+        logging.debug("Server response:\n%s" % (respdata or "<empty>"))
+        if respdata:
+            r = json.loads(respdata.decode("utf-8"))
+        else:
+            r = None
+        return r
+
     def do(self, args, argv):
         """Do command"""
         print("Not implemented")
@@ -221,11 +254,11 @@ class ProjectCommand(SubCommand):
         parser.add_argument("--verbose", "-v", action="store_true",
                             help="Show details about projects")
         args = parser.parse_args(argv)
-        r = self.api_do("get-projects")
+        r = self.rest_api_do(url_cmd="projects", request_method='get')
         if args.raw:
             print(json.dumps(r, indent=2, separators=",:"))
             return 0
-        for p in r:
+        for p in r['results']:
             print(p["name"])
             if args.verbose:
                 for k, v in p.items():
@@ -239,8 +272,8 @@ class ProjectCommand(SubCommand):
         parser.add_argument("name", nargs="+",
                             help="The name of project to show info")
         args = parser.parse_args(argv)
-        r = self.api_do("get-projects")
-        for p in r:
+        r = self.rest_api_do(url_cmd="projects", request_method='get')
+        for p in r['results']:
             if not p["name"] in args.name:
                 continue
             if len(args.name) > 1:
@@ -263,12 +296,15 @@ class ProjectCommand(SubCommand):
         parser.add_argument("--desc", "-d", default="",
                             help="Project short discription")
         args = parser.parse_args(argv)
-        self.api_do("add-project",
-                    name=args.name,
-                    mailing_list=args.mailing_list,
-                    url=args.url,
-                    git=args.git,
-                    description=args.desc)
+
+        self.rest_api_do(url_cmd="projects",
+                         request_method='post',
+                         content_type='application/json',
+                         name=args.name,
+                         mailing_list=args.mailing_list,
+                         url=args.url,
+                         git=args.git,
+                         description=args.desc)
 
     def update_one_project(self, wd, project):
         logging.info("Updating project '%s'", project["name"])
@@ -320,16 +356,17 @@ class ProjectCommand(SubCommand):
             except Exception as e:
                 logging.warn("Failed to push the new head to patchew mirror: %s",
                              str(e))
-        self.api_do("update-project-head", project=project["name"],
-                                           old_head=old_head,
-                                           new_head=new_head,
-                                           message_ids=msgids)
+        url = "project/" + project.id + "/update_project_head/"
+        self.rest_api_do("project-head",old_head=old_head,
+                                        new_head=new_head,
+                                        message_ids=msgids)
 
     def update_project(self, argv):
         parser = argparse.ArgumentParser()
         parser.add_argument("--name", "-n", help="Name of the project")
         args = parser.parse_args(argv)
-        projects = self.api_do("get-projects", name=args.name)
+        projects = self.rest_api_do("projects")
+        projects = [p for p in projects['results'] if p['name'] == args.name]
         wd = tempfile.mkdtemp()
         logging.debug("TMPDIR: %s", wd)
         try:
-- 
2.15.1 (Apple Git-101)




More information about the Patchew-devel mailing list