Add token based authentication for post/update/delete 87/28787/24
authorrohitsakala <rohitsakala@gmail.com>
Thu, 16 Feb 2017 07:52:05 +0000 (13:22 +0530)
committerRohit Sakala <rohitsakala@gmail.com>
Tue, 21 Feb 2017 19:32:25 +0000 (19:32 +0000)
As the mongodb database is not so secure today, this has been added.
The token is stored in the mongoDB database. For now, authenticate variable is set
false so that there would be no problem in accessing the databse by jenkins
jobs.

JIRA: FUNCTEST-730

Change-Id: I12b3907d650fc63efbdb031ebf3dd09519750109
Signed-off-by: rohitsakala <rohitsakala@gmail.com>
utils/test/testapi/etc/config.ini
utils/test/testapi/opnfv_testapi/cmd/server.py
utils/test/testapi/opnfv_testapi/common/config.py
utils/test/testapi/opnfv_testapi/common/constants.py
utils/test/testapi/opnfv_testapi/resources/handlers.py
utils/test/testapi/opnfv_testapi/tests/unit/test_base.py

index 0edb73a..77cc6c6 100644 (file)
@@ -11,6 +11,7 @@ dbname = test_results_collection
 port = 8000
 # With debug_on set to true, error traces will be shown in HTTP responses
 debug = True
+authenticate = False
 
 [swagger]
 base_url = http://localhost:8000
index 3e0484f..013ee66 100644 (file)
@@ -57,6 +57,7 @@ def make_app():
         url_mappings.mappings,
         db=db,
         debug=CONF.api_debug_on,
+        auth=CONF.api_authenticate_on
     )
 
 
index 82d9c4d..84a1273 100644 (file)
@@ -34,6 +34,7 @@ class APIConfig:
         self.mongo_dbname = None
         self.api_port = None
         self.api_debug_on = None
+        self.api_authenticate_on = None
         self._parser = None
         self.swagger_base_url = None
 
@@ -77,6 +78,9 @@ class APIConfig:
 
         obj.api_port = obj._get_int_parameter("api", "port")
         obj.api_debug_on = obj._get_bool_parameter("api", "debug")
+        obj.api_authenticate_on = obj._get_bool_parameter("api",
+                                                          "authenticate")
+
         obj.swagger_base_url = obj._get_parameter("swagger", "base_url")
 
         return obj
@@ -90,4 +94,5 @@ class APIConfig:
                                              self.mongo_dbname,
                                              self.api_port,
                                              self.api_debug_on,
+                                             self.api_authenticate_on,
                                              self.swagger_base_url)
index 4d39a14..71bd952 100644 (file)
@@ -10,6 +10,7 @@
 
 DEFAULT_REPRESENTATION = "application/json"
 HTTP_BAD_REQUEST = 400
+HTTP_UNAUTHORIZED = 401
 HTTP_FORBIDDEN = 403
 HTTP_NOT_FOUND = 404
 HTTP_OK = 200
index 89e91b3..63e2e8b 100644 (file)
@@ -21,6 +21,7 @@
 ##############################################################################
 
 from datetime import datetime
+import functools
 import json
 
 from tornado import gen
@@ -43,6 +44,7 @@ class GenericApiHandler(web.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":
@@ -70,8 +72,29 @@ class GenericApiHandler(web.RequestHandler):
         cls_data = self.table_cls.from_dict(data)
         return cls_data.format_http()
 
+    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(web.HTTP_UNAUTHORIZED,
+                                        "No Authentication Header.")
+                query = {'access_token': token}
+                check = yield self._eval_db_find_one(query, 'tokens')
+                if not check:
+                    raise web.HTTPError(web.HTTP_FORBIDDEN,
+                                        "Invalid Token.")
+            ret = yield gen.coroutine(method)(self, *args, **kwargs)
+            raise gen.Return(ret)
+        return wrapper
+
     @web.asynchronous
     @gen.coroutine
+    @authenticate
     def _create(self, miss_checks, db_checks, **kwargs):
         """
         :param miss_checks: [miss1, miss2]
@@ -137,6 +160,7 @@ class GenericApiHandler(web.RequestHandler):
 
     @web.asynchronous
     @gen.coroutine
+    @authenticate
     def _delete(self, query):
         data = yield self._eval_db_find_one(query)
         if data is None:
@@ -149,6 +173,7 @@ class GenericApiHandler(web.RequestHandler):
 
     @web.asynchronous
     @gen.coroutine
+    @authenticate
     def _update(self, query, db_keys):
         if self.json_args is None:
             raise web.HTTPError(constants.HTTP_BAD_REQUEST, "No payload")
index 84d611b..b2be8d5 100644 (file)
@@ -35,6 +35,7 @@ class TestBase(testing.AsyncHTTPTestCase):
             url_mappings.mappings,
             db=fake_pymongo,
             debug=True,
+            auth=False
         )
 
     def create_d(self, *args):