replace self-defined http codes with standard definitions
[releng.git] / utils / test / testapi / opnfv_testapi / resources / handlers.py
index 9fc5d6b..bf8a92b 100644 (file)
 # feng.xiaowei@zte.com.cn remove DashboardHandler            5-30-2016
 ##############################################################################
 
-import json
 from datetime import datetime
+import functools
+import httplib
+import json
 
 from tornado import gen
-from tornado.web import RequestHandler, asynchronous, HTTPError
+from tornado import web
 
-from models import CreateResponse
-from opnfv_testapi.common.constants import DEFAULT_REPRESENTATION, \
-    HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_FORBIDDEN
+import models
 from opnfv_testapi.tornado_swagger import swagger
 
+DEFAULT_REPRESENTATION = "application/json"
+
 
-class GenericApiHandler(RequestHandler):
+class GenericApiHandler(web.RequestHandler):
     def __init__(self, application, request, **kwargs):
         super(GenericApiHandler, self).__init__(application, request, **kwargs)
         self.db = self.settings["db"]
@@ -44,6 +46,7 @@ class GenericApiHandler(RequestHandler):
         self.db_testcases = 'testcases'
         self.db_results = 'results'
         self.db_scenarios = 'scenarios'
+        self.auth = self.settings["auth"]
 
     def prepare(self):
         if self.request.method != "GET" and self.request.method != "DELETE":
@@ -53,9 +56,9 @@ class GenericApiHandler(RequestHandler):
                     try:
                         self.json_args = json.loads(self.request.body)
                     except (ValueError, KeyError, TypeError) as error:
-                        raise HTTPError(HTTP_BAD_REQUEST,
-                                        "Bad Json format [{}]".
-                                        format(error))
+                        raise web.HTTPError(httplib.BAD_REQUEST,
+                                            "Bad Json format [{}]".
+                                            format(error))
 
     def finish_request(self, json_object=None):
         if json_object:
@@ -65,28 +68,47 @@ class GenericApiHandler(RequestHandler):
 
     def _create_response(self, resource):
         href = self.request.full_url() + '/' + str(resource)
-        return CreateResponse(href=href).format()
+        return models.CreateResponse(href=href).format()
 
     def format_data(self, data):
         cls_data = self.table_cls.from_dict(data)
         return cls_data.format_http()
 
-    @asynchronous
-    @gen.coroutine
+    def authenticate(method):
+        @web.asynchronous
+        @gen.coroutine
+        @functools.wraps(method)
+        def wrapper(self, *args, **kwargs):
+            if self.auth:
+                try:
+                    token = self.request.headers['X-Auth-Token']
+                except KeyError:
+                    raise web.HTTPError(httplib.UNAUTHORIZED,
+                                        "No Authentication Header.")
+                query = {'access_token': token}
+                check = yield self._eval_db_find_one(query, 'tokens')
+                if not check:
+                    raise web.HTTPError(httplib.FORBIDDEN,
+                                        "Invalid Token.")
+            ret = yield gen.coroutine(method)(self, *args, **kwargs)
+            raise gen.Return(ret)
+        return wrapper
+
+    @authenticate
     def _create(self, miss_checks, db_checks, **kwargs):
         """
         :param miss_checks: [miss1, miss2]
         :param db_checks: [(table, exist, query, error)]
         """
         if self.json_args is None:
-            raise HTTPError(HTTP_BAD_REQUEST, "no body")
+            raise web.HTTPError(httplib.BAD_REQUEST, "no body")
 
         data = self.table_cls.from_dict(self.json_args)
         for miss in miss_checks:
             miss_data = data.__getattribute__(miss)
             if miss_data is None or miss_data == '':
-                raise HTTPError(HTTP_BAD_REQUEST,
-                                '{} missing'.format(miss))
+                raise web.HTTPError(httplib.BAD_REQUEST,
+                                    '{} missing'.format(miss))
 
         for k, v in kwargs.iteritems():
             data.__setattr__(k, v)
@@ -95,7 +117,7 @@ class GenericApiHandler(RequestHandler):
             check = yield self._eval_db_find_one(query(data), table)
             if (exist and not check) or (not exist and check):
                 code, message = error(data)
-                raise HTTPError(code, message)
+                raise web.HTTPError(code, message)
 
         if self.table != 'results':
             data.creation_date = datetime.now()
@@ -107,7 +129,7 @@ class GenericApiHandler(RequestHandler):
             resource = _id
         self.finish_request(self._create_response(resource))
 
-    @asynchronous
+    @web.asynchronous
     @gen.coroutine
     def _list(self, query=None, res_op=None, *args, **kwargs):
         if query is None:
@@ -126,40 +148,38 @@ class GenericApiHandler(RequestHandler):
             res = res_op(data, *args)
         self.finish_request(res)
 
-    @asynchronous
+    @web.asynchronous
     @gen.coroutine
     def _get_one(self, query):
         data = yield self._eval_db_find_one(query)
         if data is None:
-            raise HTTPError(HTTP_NOT_FOUND,
-                            "[{}] not exist in table [{}]"
-                            .format(query, self.table))
+            raise web.HTTPError(httplib.NOT_FOUND,
+                                "[{}] not exist in table [{}]"
+                                .format(query, self.table))
         self.finish_request(self.format_data(data))
 
-    @asynchronous
-    @gen.coroutine
+    @authenticate
     def _delete(self, query):
         data = yield self._eval_db_find_one(query)
         if data is None:
-            raise HTTPError(HTTP_NOT_FOUND,
-                            "[{}] not exit in table [{}]"
-                            .format(query, self.table))
+            raise web.HTTPError(httplib.NOT_FOUND,
+                                "[{}] not exit in table [{}]"
+                                .format(query, self.table))
 
         yield self._eval_db(self.table, 'remove', query)
         self.finish_request()
 
-    @asynchronous
-    @gen.coroutine
+    @authenticate
     def _update(self, query, db_keys):
         if self.json_args is None:
-            raise HTTPError(HTTP_BAD_REQUEST, "No payload")
+            raise web.HTTPError(httplib.BAD_REQUEST, "No payload")
 
         # check old data exist
         from_data = yield self._eval_db_find_one(query)
         if from_data is None:
-            raise HTTPError(HTTP_NOT_FOUND,
-                            "{} could not be found in table [{}]"
-                            .format(query, self.table))
+            raise web.HTTPError(httplib.NOT_FOUND,
+                                "{} could not be found in table [{}]"
+                                .format(query, self.table))
 
         data = self.table_cls.from_dict(from_data)
         # check new data exist
@@ -167,13 +187,12 @@ class GenericApiHandler(RequestHandler):
         if not equal:
             to_data = yield self._eval_db_find_one(new_query)
             if to_data is not None:
-                raise HTTPError(HTTP_FORBIDDEN,
-                                "{} already exists in table [{}]"
-                                .format(new_query, self.table))
+                raise web.HTTPError(httplib.FORBIDDEN,
+                                    "{} already exists in table [{}]"
+                                    .format(new_query, self.table))
 
         # we merge the whole document """
-        edit_request = data.format()
-        edit_request.update(self._update_requests(data))
+        edit_request = self._update_requests(data)
 
         """ Updating the DB """
         yield self._eval_db(self.table, 'update', query, edit_request,
@@ -187,8 +206,11 @@ class GenericApiHandler(RequestHandler):
             request = self._update_request(request, k, v,
                                            data.__getattribute__(k))
         if not request:
-            raise HTTPError(HTTP_FORBIDDEN, "Nothing to update")
-        return request
+            raise web.HTTPError(httplib.FORBIDDEN, "Nothing to update")
+
+        edit_request = data.format()
+        edit_request.update(request)
+        return edit_request
 
     @staticmethod
     def _update_request(edit_request, key, new_value, old_value):
@@ -228,7 +250,7 @@ class GenericApiHandler(RequestHandler):
 
 
 class VersionHandler(GenericApiHandler):
-    @swagger.operation(nickname='List all versions')
+    @swagger.operation(nickname='listAllVersions')
     def get(self):
         """
             @description: list all supported versions