Adding Authentication Connector plugin system
[osm/NBI.git] / osm_nbi / auth.py
index 572ab88..5dedf56 100644 (file)
@@ -1,25 +1,89 @@
+# -*- coding: utf-8 -*-
+
+"""
+Authenticator is responsible for authenticating the users,
+create the tokens unscoped and scoped, retrieve the role
+list inside the projects that they are inserted
+"""
+
+__author__ = "Eduardo Sousa <eduardosousa@av.it.pt>"
+__date__ = "$27-jul-2018 23:59:59$"
+
+import logging
+
 import cherrypy
 from base64 import standard_b64decode
 from http import HTTPStatus
 
-
+from authconn_keystone import AuthconnKeystone
 from engine import EngineException
 
-__author__ = "Eduardo Sousa <eduardosousa@av.it.pt>"
-
 
-class AuthenticatorException(Exception):
+class AuthException(Exception):
     def __init__(self, message, http_code=HTTPStatus.UNAUTHORIZED):
         self.http_code = http_code
         Exception.__init__(self, message)
 
 
-class Authenticator(object):
+class Authenticator:
+    """
+    This class should hold all the mechanisms for User Authentication and
+    Authorization. Initially it should support Openstack Keystone as a
+    backend through a plugin model where more backends can be added and a
+    RBAC model to manage permissions on operations.
+    """
+
     def __init__(self, engine):
+        """
+        Authenticator initializer. Setup the initial state of the object,
+        while it waits for the config dictionary and database initialization.
+
+        Note: engine is only here until all the calls can to it can be replaced.
+
+        :param engine: reference to engine object used.
+        """
         super().__init__()
 
         self.engine = engine
 
+        self.backend = None
+        self.config = None
+        self.db = None
+        self.logger = logging.getLogger("nbi.authenticator")
+
+    def start(self, config):
+        """
+        Method to configure the Authenticator object. This method should be called
+        after object creation. It is responsible by initializing the selected backend,
+        as well as the initialization of the database connection.
+
+        :param config: dictionary containing the relevant parameters for this object.
+        """
+        self.config = config
+
+        try:
+            if not self.backend:
+                if config["authenticator"]["backend"] == "keystone":
+                    self.backend = AuthconnKeystone(self.config["authenticator"])
+            if not self.db:
+                pass
+                # TODO: Implement database initialization
+                # NOTE: Database needed to store the mappings
+        except Exception as e:
+            raise AuthException(str(e))
+
+        pass
+
+    def init_db(self, target_version='1.0'):
+        """
+        Check if the database has been initialized. If not, create the required tables
+        and insert the predefined mappings between roles and permissions.
+
+        :param target_version: schema version that should be present in the database.
+        :return: None if OK, exception if error or version is different.
+        """
+        pass
+
     def authorize(self):
         token = None
         user_passwd64 = None
@@ -60,7 +124,7 @@ class Authenticator(object):
             if cherrypy.session.get('Authorization'):
                 del cherrypy.session['Authorization']
             cherrypy.response.headers["WWW-Authenticate"] = 'Bearer realm="{}"'.format(e)
-            raise AuthenticatorException(str(e))
+            raise AuthException(str(e))
 
     def new_token(self, session, indata, remote):
         return self.engine.new_token(session, indata, remote)