bug 1035. Load role permissions from nbi.py 'valid_url_methods' instead of 'resources... 14/8714/2
authortierno <alfonso.tiernosepulveda@telefonica.com>
Mon, 23 Mar 2020 09:24:10 +0000 (09:24 +0000)
committertierno <alfonso.tiernosepulveda@telefonica.com>
Tue, 24 Mar 2020 13:44:54 +0000 (13:44 +0000)
Change-Id: I84a80f8cef886cbce9b22819ead04ae14d31af79
Signed-off-by: tierno <alfonso.tiernosepulveda@telefonica.com>
devops-stages/stage-test.sh
osm_nbi/admin_topics.py
osm_nbi/auth.py
osm_nbi/authconn.py
osm_nbi/authconn_internal.py
osm_nbi/authconn_keystone.py
osm_nbi/engine.py
osm_nbi/tests/test_admin_topics.py
osm_nbi/tests/test_descriptor_topics.py

index 71d2252..87802ea 100755 (executable)
@@ -13,5 +13,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+rm -f nosetests.xml
 tox  # flake8 unittest
 
 tox  # flake8 unittest
 
index 565d763..9f591fc 100644 (file)
@@ -1027,10 +1027,10 @@ class RoleTopicAuth(BaseTopic):
     schema_edit = roles_edit_schema
     multiproject = False
 
     schema_edit = roles_edit_schema
     multiproject = False
 
-    def __init__(self, db, fs, msg, auth, ops):
+    def __init__(self, db, fs, msg, auth):
         BaseTopic.__init__(self, db, fs, msg, auth)
         # self.auth = auth
         BaseTopic.__init__(self, db, fs, msg, auth)
         # self.auth = auth
-        self.operations = ops
+        self.operations = auth.role_permissions
         # self.topic = "roles_operations" if isinstance(auth, AuthconnKeystone) else "roles"
 
     @staticmethod
         # self.topic = "roles_operations" if isinstance(auth, AuthconnKeystone) else "roles"
 
     @staticmethod
index f756d9d..9098de7 100644 (file)
@@ -114,9 +114,9 @@ class Authenticator:
                                         .format(config["message"]["driver"]))
             if not self.backend:
                 if config["authentication"]["backend"] == "keystone":
                                         .format(config["message"]["driver"]))
             if not self.backend:
                 if config["authentication"]["backend"] == "keystone":
-                    self.backend = AuthconnKeystone(self.config["authentication"], self.db)
+                    self.backend = AuthconnKeystone(self.config["authentication"], self.db, self.role_permissions)
                 elif config["authentication"]["backend"] == "internal":
                 elif config["authentication"]["backend"] == "internal":
-                    self.backend = AuthconnInternal(self.config["authentication"], self.db)
+                    self.backend = AuthconnInternal(self.config["authentication"], self.db, self.role_permissions)
                     self._internal_tokens_prune()
                 else:
                     raise AuthException("Unknown authentication backend: {}"
                     self._internal_tokens_prune()
                 else:
                     raise AuthException("Unknown authentication backend: {}"
index c43c339..bbcf342 100644 (file)
@@ -110,16 +110,16 @@ class Authconn:
     Each Auth backend connector plugin must be a subclass of
     Authconn class.
     """
     Each Auth backend connector plugin must be a subclass of
     Authconn class.
     """
-    def __init__(self, config, db):
+    def __init__(self, config, db, role_permissions):
         """
         Constructor of the Authconn class.
         """
         Constructor of the Authconn class.
-
-        Note: each subclass
-
         :param config: configuration dictionary containing all the
         necessary configuration parameters.
         :param config: configuration dictionary containing all the
         necessary configuration parameters.
+        :param db: internal database classs
+        :param role_permissions: read only role permission list
         """
         self.config = config
         """
         self.config = config
+        self.role_permissions = role_permissions
 
     def authenticate(self, credentials, token_info=None):
         """
 
     def authenticate(self, credentials, token_info=None):
         """
index 1977aca..88b276d 100644 (file)
@@ -46,8 +46,8 @@ class AuthconnInternal(Authconn):
     token_time_window = 2   # seconds
     token_delay = 1   # seconds to wait upon second request within time window
 
     token_time_window = 2   # seconds
     token_delay = 1   # seconds to wait upon second request within time window
 
-    def __init__(self, config, db):
-        Authconn.__init__(self, config, db)
+    def __init__(self, config, db, role_permissions):
+        Authconn.__init__(self, config, db, role_permissions)
         self.logger = logging.getLogger("nbi.authenticator.internal")
 
         self.db = db
         self.logger = logging.getLogger("nbi.authenticator.internal")
 
         self.db = db
index c69d64b..d71408a 100644 (file)
@@ -45,8 +45,8 @@ from osm_nbi.validation import is_valid_uuid
 
 
 class AuthconnKeystone(Authconn):
 
 
 class AuthconnKeystone(Authconn):
-    def __init__(self, config, db):
-        Authconn.__init__(self, config, db)
+    def __init__(self, config, db, role_permissions):
+        Authconn.__init__(self, config, db, role_permissions)
 
         self.logger = logging.getLogger("nbi.authenticator.keystone")
         self.domains_id2name = {}
 
         self.logger = logging.getLogger("nbi.authenticator.keystone")
         self.domains_id2name = {}
index cd02b1d..34f0f14 100644 (file)
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 import logging
 # limitations under the License.
 
 import logging
-import yaml
+import yaml
 from osm_common import dbmongo, dbmemory, fslocal, fsmongo, msglocal, msgkafka, version as common_version
 from osm_common.dbbase import DbException
 from osm_common.fsbase import FsException
 from osm_common import dbmongo, dbmemory, fslocal, fsmongo, msglocal, msgkafka, version as common_version
 from osm_common.dbbase import DbException
 from osm_common.fsbase import FsException
@@ -31,7 +31,7 @@ from osm_nbi.descriptor_topics import VnfdTopic, NsdTopic, PduTopic, NstTopic, V
 from osm_nbi.instance_topics import NsrTopic, VnfrTopic, NsLcmOpTopic, NsiTopic, NsiLcmOpTopic
 from osm_nbi.pmjobs_topics import PmJobsTopic
 from base64 import b64encode
 from osm_nbi.instance_topics import NsrTopic, VnfrTopic, NsLcmOpTopic, NsiTopic, NsiLcmOpTopic
 from osm_nbi.pmjobs_topics import PmJobsTopic
 from base64 import b64encode
-from os import urandom, path
+from os import urandom   # , path
 from threading import Lock
 
 __author__ = "Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>"
 from threading import Lock
 
 __author__ = "Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>"
@@ -75,7 +75,7 @@ class Engine(object):
         self.msg = None
         self.authconn = None
         self.config = None
         self.msg = None
         self.authconn = None
         self.config = None
-        self.operations = None
+        self.operations = None
         self.logger = logging.getLogger("nbi.engine")
         self.map_topic = {}
         self.write_lock = None
         self.logger = logging.getLogger("nbi.engine")
         self.map_topic = {}
         self.write_lock = None
@@ -127,43 +127,42 @@ class Engine(object):
                         config["message"]["driver"]))
             if not self.authconn:
                 if config["authentication"]["backend"] == "keystone":
                         config["message"]["driver"]))
             if not self.authconn:
                 if config["authentication"]["backend"] == "keystone":
-                    self.authconn = AuthconnKeystone(config["authentication"], self.db)
+                    self.authconn = AuthconnKeystone(config["authentication"], self.db,
+                                                     self.authenticator.role_permissions)
                 else:
                 else:
-                    self.authconn = AuthconnInternal(config["authentication"], self.db)
-            if not self.operations:
-                if "resources_to_operations" in config["rbac"]:
-                    resources_to_operations_file = config["rbac"]["resources_to_operations"]
-                else:
-                    possible_paths = (
-                        __file__[:__file__.rfind("engine.py")] + "resources_to_operations.yml",
-                        "./resources_to_operations.yml"
-                    )
-                    for config_file in possible_paths:
-                        if path.isfile(config_file):
-                            resources_to_operations_file = config_file
-                            break
-                    if not resources_to_operations_file:                   
-                        raise EngineException("Invalid permission configuration: resources_to_operations file missing")
-
-                with open(resources_to_operations_file, 'r') as f:
-                    resources_to_operations = yaml.load(f, Loader=yaml.Loader)
-
-                self.operations = []
-
-                for _, value in resources_to_operations["resources_to_operations"].items():
-                    if value not in self.operations:
-                        self.operations += [value]
+                    self.authconn = AuthconnInternal(config["authentication"], self.db,
+                                                     self.authenticator.role_permissions)
+            # if not self.operations:
+            #     if "resources_to_operations" in config["rbac"]:
+            #         resources_to_operations_file = config["rbac"]["resources_to_operations"]
+            #     else:
+            #         possible_paths = (
+            #             __file__[:__file__.rfind("engine.py")] + "resources_to_operations.yml",
+            #             "./resources_to_operations.yml"
+            #         )
+            #         for config_file in possible_paths:
+            #             if path.isfile(config_file):
+            #                 resources_to_operations_file = config_file
+            #                 break
+            #         if not resources_to_operations_file:
+            #             raise EngineException("Invalid permission configuration:"
+            #                 "resources_to_operations file missing")
+            #
+            #     with open(resources_to_operations_file, 'r') as f:
+            #         resources_to_operations = yaml.load(f, Loader=yaml.Loader)
+            #
+            #     self.operations = []
+            #
+            #     for _, value in resources_to_operations["resources_to_operations"].items():
+            #         if value not in self.operations:
+            #             self.operations += [value]
 
             self.write_lock = Lock()
             # create one class per topic
             for topic, topic_class in self.map_from_topic_to_class.items():
                 # if self.auth and topic_class in (UserTopicAuth, ProjectTopicAuth):
                 #     self.map_topic[topic] = topic_class(self.db, self.fs, self.msg, self.auth)
 
             self.write_lock = Lock()
             # create one class per topic
             for topic, topic_class in self.map_from_topic_to_class.items():
                 # if self.auth and topic_class in (UserTopicAuth, ProjectTopicAuth):
                 #     self.map_topic[topic] = topic_class(self.db, self.fs, self.msg, self.auth)
-                if self.authconn and topic_class == RoleTopicAuth:
-                    self.map_topic[topic] = topic_class(self.db, self.fs, self.msg, self.authconn,
-                                                        self.operations)
-                else:
-                    self.map_topic[topic] = topic_class(self.db, self.fs, self.msg, self.authconn)
+                self.map_topic[topic] = topic_class(self.db, self.fs, self.msg, self.authconn)
             
             self.map_topic["pm_jobs"] = PmJobsTopic(self.db, config["prometheus"].get("host"),
                                                     config["prometheus"].get("port"))
             
             self.map_topic["pm_jobs"] = PmJobsTopic(self.db, config["prometheus"].get("host"),
                                                     config["prometheus"].get("port"))
index a28953b..596faeb 100755 (executable)
@@ -50,7 +50,7 @@ class Test_ProjectTopicAuth(TestCase):
         self.db = Mock(dbbase.DbBase())
         self.fs = Mock(fsbase.FsBase())
         self.msg = Mock(msgbase.MsgBase())
         self.db = Mock(dbbase.DbBase())
         self.fs = Mock(fsbase.FsBase())
         self.msg = Mock(msgbase.MsgBase())
-        self.auth = Mock(authconn.Authconn(None, None))
+        self.auth = Mock(authconn.Authconn(None, None, None))
         self.topic = ProjectTopicAuth(self.db, self.fs, self.msg, self.auth)
         self.fake_session = {"username": self.test_name, "project_id": (test_pid,), "method": None,
                              "admin": True, "force": False, "public": False, "allow_show_user_project_role": True}
         self.topic = ProjectTopicAuth(self.db, self.fs, self.msg, self.auth)
         self.fake_session = {"username": self.test_name, "project_id": (test_pid,), "method": None,
                              "admin": True, "force": False, "public": False, "allow_show_user_project_role": True}
@@ -210,8 +210,9 @@ class Test_RoleTopicAuth(TestCase):
         self.db = Mock(dbbase.DbBase())
         self.fs = Mock(fsbase.FsBase())
         self.msg = Mock(msgbase.MsgBase())
         self.db = Mock(dbbase.DbBase())
         self.fs = Mock(fsbase.FsBase())
         self.msg = Mock(msgbase.MsgBase())
-        self.auth = Mock(authconn.Authconn(None, None))
-        self.topic = RoleTopicAuth(self.db, self.fs, self.msg, self.auth, self.test_operations)
+        self.auth = Mock(authconn.Authconn(None, None, None))
+        self.auth.role_permissions = self.test_operations
+        self.topic = RoleTopicAuth(self.db, self.fs, self.msg, self.auth)
         self.fake_session = {"username": test_name, "project_id": (test_pid,), "method": None,
                              "admin": True, "force": False, "public": False, "allow_show_user_project_role": True}
 
         self.fake_session = {"username": test_name, "project_id": (test_pid,), "method": None,
                              "admin": True, "force": False, "public": False, "allow_show_user_project_role": True}
 
@@ -370,7 +371,7 @@ class Test_UserTopicAuth(TestCase):
         self.db = Mock(dbbase.DbBase())
         self.fs = Mock(fsbase.FsBase())
         self.msg = Mock(msgbase.MsgBase())
         self.db = Mock(dbbase.DbBase())
         self.fs = Mock(fsbase.FsBase())
         self.msg = Mock(msgbase.MsgBase())
-        self.auth = Mock(authconn.Authconn(None, None))
+        self.auth = Mock(authconn.Authconn(None, None, None))
         self.topic = UserTopicAuth(self.db, self.fs, self.msg, self.auth)
         self.fake_session = {"username": test_name, "project_id": (test_pid,), "method": None,
                              "admin": True, "force": False, "public": False, "allow_show_user_project_role": True}
         self.topic = UserTopicAuth(self.db, self.fs, self.msg, self.auth)
         self.fake_session = {"username": test_name, "project_id": (test_pid,), "method": None,
                              "admin": True, "force": False, "public": False, "allow_show_user_project_role": True}
@@ -588,7 +589,7 @@ class Test_CommonVimWimSdn(TestCase):
         self.db = Mock(dbbase.DbBase())
         self.fs = Mock(fsbase.FsBase())
         self.msg = Mock(msgbase.MsgBase())
         self.db = Mock(dbbase.DbBase())
         self.fs = Mock(fsbase.FsBase())
         self.msg = Mock(msgbase.MsgBase())
-        self.auth = Mock(authconn.Authconn(None, None))
+        self.auth = Mock(authconn.Authconn(None, None, None))
         self.topic = CommonVimWimSdn(self.db, self.fs, self.msg, self.auth)
         # Use WIM schemas for testing because they are the simplest
         self.topic.topic = "wims"
         self.topic = CommonVimWimSdn(self.db, self.fs, self.msg, self.auth)
         # Use WIM schemas for testing because they are the simplest
         self.topic.topic = "wims"
index 6e39030..773131c 100755 (executable)
@@ -84,7 +84,7 @@ class Test_VnfdTopic(TestCase):
         self.db = Mock(dbbase.DbBase())
         self.fs = Mock(fsbase.FsBase())
         self.msg = Mock(msgbase.MsgBase())
         self.db = Mock(dbbase.DbBase())
         self.fs = Mock(fsbase.FsBase())
         self.msg = Mock(msgbase.MsgBase())
-        self.auth = Mock(authconn.Authconn(None, None))
+        self.auth = Mock(authconn.Authconn(None, None, None))
         self.topic = VnfdTopic(self.db, self.fs, self.msg, self.auth)
 
     def test_new_vnfd(self):
         self.topic = VnfdTopic(self.db, self.fs, self.msg, self.auth)
 
     def test_new_vnfd(self):
@@ -512,7 +512,7 @@ class Test_NsdTopic(TestCase):
         self.db = Mock(dbbase.DbBase())
         self.fs = Mock(fsbase.FsBase())
         self.msg = Mock(msgbase.MsgBase())
         self.db = Mock(dbbase.DbBase())
         self.fs = Mock(fsbase.FsBase())
         self.msg = Mock(msgbase.MsgBase())
-        self.auth = Mock(authconn.Authconn(None, None))
+        self.auth = Mock(authconn.Authconn(None, None, None))
         self.topic = NsdTopic(self.db, self.fs, self.msg, self.auth)
 
     def test_new_nsd(self):
         self.topic = NsdTopic(self.db, self.fs, self.msg, self.auth)
 
     def test_new_nsd(self):