From 929e91fe4bc2e0d63c82d9003b538bf36d01044e Mon Sep 17 00:00:00 2001
From: Sinisa Veseli <sveseli@aps.anl.gov>
Date: Mon, 13 Apr 2015 13:06:43 +0000
Subject: [PATCH] moved common authorization/authentication classes into their
 own module to better reflect their functionality; added checks for admin role
 name into principal retrievers

---
 .../common/service/{impl => auth}/__init__.py |  0
 .../authorizationPrincipalAuthenticator.py    |  0
 .../authorizationPrincipalManager.py}         | 57 +++++++------------
 .../auth/authorizationPrincipalRetriever.py   | 36 ++++++++++++
 .../cryptedPasswordPrincipalAuthenticator.py  |  0
 .../{impl => auth}/dbPrincipalRetriever.py    |  7 +--
 .../ldapPasswordPrincipalAuthenticator.py     |  0
 .../{impl => auth}/noOpPrincipalRetriever.py  |  5 +-
 .../impl/authorizationPrincipalRetriever.py   | 25 --------
 9 files changed, 62 insertions(+), 68 deletions(-)
 rename src/python/dm/common/service/{impl => auth}/__init__.py (100%)
 rename src/python/dm/common/service/{impl => auth}/authorizationPrincipalAuthenticator.py (100%)
 rename src/python/dm/common/service/{impl/authorizationManager.py => auth/authorizationPrincipalManager.py} (67%)
 create mode 100755 src/python/dm/common/service/auth/authorizationPrincipalRetriever.py
 rename src/python/dm/common/service/{impl => auth}/cryptedPasswordPrincipalAuthenticator.py (100%)
 rename src/python/dm/common/service/{impl => auth}/dbPrincipalRetriever.py (74%)
 rename src/python/dm/common/service/{impl => auth}/ldapPasswordPrincipalAuthenticator.py (100%)
 rename src/python/dm/common/service/{impl => auth}/noOpPrincipalRetriever.py (82%)
 delete mode 100755 src/python/dm/common/service/impl/authorizationPrincipalRetriever.py

diff --git a/src/python/dm/common/service/impl/__init__.py b/src/python/dm/common/service/auth/__init__.py
similarity index 100%
rename from src/python/dm/common/service/impl/__init__.py
rename to src/python/dm/common/service/auth/__init__.py
diff --git a/src/python/dm/common/service/impl/authorizationPrincipalAuthenticator.py b/src/python/dm/common/service/auth/authorizationPrincipalAuthenticator.py
similarity index 100%
rename from src/python/dm/common/service/impl/authorizationPrincipalAuthenticator.py
rename to src/python/dm/common/service/auth/authorizationPrincipalAuthenticator.py
diff --git a/src/python/dm/common/service/impl/authorizationManager.py b/src/python/dm/common/service/auth/authorizationPrincipalManager.py
similarity index 67%
rename from src/python/dm/common/service/impl/authorizationManager.py
rename to src/python/dm/common/service/auth/authorizationPrincipalManager.py
index f5371b62..1c205261 100755
--- a/src/python/dm/common/service/impl/authorizationManager.py
+++ b/src/python/dm/common/service/auth/authorizationPrincipalManager.py
@@ -7,49 +7,33 @@ from dm.common.objects.dmObjectManager import DmObjectManager
 from dm.common.utility.configurationManager import ConfigurationManager
 from dm.common.utility.objectCache import ObjectCache
 from dm.common.utility.cryptUtility import CryptUtility
+from dm.common.utility.objectUtility import ObjectUtility
+from dm.common.utility.singleton import Singleton
 
-class AuthorizationManager(DmObjectManager):
+class AuthorizationPrincipalManager(DmObjectManager, Singleton):
 
     DEFAULT_CACHE_SIZE = 10000 # number of items
     DEFAULT_CACHE_OBJECT_LIFETIME = 3600 # seconds
 
-    CONFIG_SECTION_NAME = 'AuthorizationManager'
-    ADMIN_GROUP_NAME_KEY = 'admingroupname'
+    CONFIG_SECTION_NAME = 'AuthorizationPrincipalManager'
+    ADMIN_ROLE_NAME_KEY = 'adminrolename'
     PRINCIPAL_RETRIEVER_KEY = 'principalretriever'
     PRINCIPAL_AUTHENTICATOR_KEY = 'principalauthenticator'
 
-    # Get singleton instance.
-    @classmethod
-    def getInstance(cls):
-        from dm.common.service.impl.authorizationManager import AuthorizationManager
-        try:
-            am = AuthorizationManager()
-        except AuthorizationManager, ex:
-            am = ex
-        return am
-
     # Singleton instance.
     __instance = None
 
     def __init__(self):
-        if AuthorizationManager.__instance:
-            raise AuthorizationManager.__instance
-        AuthorizationManager.__instance = self
+        if AuthorizationPrincipalManager.__instance:
+            return
+        AuthorizationPrincipalManager.__instance = self
         DmObjectManager.__init__(self)
         self.configurationManager = ConfigurationManager.getInstance()
         self.principalRetriever = None
         self.principalAuthenticatorList = []
-        self.objectCache = ObjectCache(AuthorizationManager.DEFAULT_CACHE_SIZE, AuthorizationManager.DEFAULT_CACHE_OBJECT_LIFETIME)
+        self.objectCache = ObjectCache(AuthorizationPrincipalManager.DEFAULT_CACHE_SIZE, AuthorizationPrincipalManager.DEFAULT_CACHE_OBJECT_LIFETIME)
         self.configure()
 
-    def createObjectInstance(self, moduleName, className, constructor):
-        self.logger.debug('Creating object: %s, %s, %s' % (moduleName, className, constructor))
-        cmd = 'from %s import %s' % (moduleName, className)
-        exec cmd
-        cmd = 'objectInstance = %s' % (constructor)
-        exec cmd
-        return objectInstance
-
     @classmethod
     def cryptPassword(cls, cleartext):
         return CryptUtility.cryptPassword(cleartext)
@@ -59,31 +43,32 @@ class AuthorizationManager(DmObjectManager):
         return CryptUtility.cryptPasswordWithPbkdf2(cleartext)
 
     def configure(self):
-        configItems = self.configurationManager.getConfigItems(AuthorizationManager.CONFIG_SECTION_NAME)
+        configItems = self.configurationManager.getConfigItems(AuthorizationPrincipalManager.CONFIG_SECTION_NAME)
         self.logger.debug('Got config items: %s' % configItems)
-        adminGroupName = self.configurationManager.getConfigOption(AuthorizationManager.CONFIG_SECTION_NAME, AuthorizationManager.ADMIN_GROUP_NAME_KEY)
+        adminRoleName = self.configurationManager.getConfigOption(AuthorizationPrincipalManager.CONFIG_SECTION_NAME, AuthorizationPrincipalManager.ADMIN_ROLE_NAME_KEY)
 
         # Create principal retriever
-        principalRetriever = self.configurationManager.getConfigOption(AuthorizationManager.CONFIG_SECTION_NAME, AuthorizationManager.PRINCIPAL_RETRIEVER_KEY)
-        (moduleName,className,constructor) = self.configurationManager.getModuleClassConstructorTuple(principalRetriever)    
+        principalRetriever = self.configurationManager.getConfigOption(AuthorizationPrincipalManager.CONFIG_SECTION_NAME, AuthorizationPrincipalManager.PRINCIPAL_RETRIEVER_KEY)
+        (moduleName,className,constructor) = self.configurationManager.getModuleClassConstructorTuple(principalRetriever, AuthorizationPrincipalManager)    
         self.logger.debug('Creating principal retriever class: %s' % className)
-        self.principalRetriever = self.createObjectInstance(moduleName, className, constructor)
-        self.principalRetriever.setAdminGroupName(adminGroupName)
+        self.principalRetriever = ObjectUtility.createObjectInstance(moduleName, className, constructor)
+        if adminRoleName is not None:
+            self.principalRetriever.setAdminRoleName(adminRoleName)
         self.logger.debug('Authorization principal retriever: %s' % (self.principalRetriever))
 
         # Create principal authenticators
         for (key,value) in configItems:
-            if key.startswith(AuthorizationManager.PRINCIPAL_AUTHENTICATOR_KEY):
-                (moduleName,className,constructor) = self.configurationManager.getModuleClassConstructorTuple(value)    
+            if key.startswith(AuthorizationPrincipalManager.PRINCIPAL_AUTHENTICATOR_KEY):
+                (moduleName,className,constructor) = self.configurationManager.getModuleClassConstructorTuple(value, AuthorizationPrincipalManager)    
                 self.logger.debug('Creating principal authenticator class: %s' % className)
-                principalAuthenticator = self.createObjectInstance(moduleName, className, constructor)
+                principalAuthenticator = ObjectUtility.createObjectInstance(moduleName, className, constructor)
                 self.addAuthorizationPrincipalAuthenticator(principalAuthenticator)
                 self.logger.debug('Authorization principal authenticator: %s' % (principalAuthenticator))
 
     def addAuthorizationPrincipalAuthenticator(self, principalAuthenticator):
         self.principalAuthenticatorList.append(principalAuthenticator)
 
-    def getAuthorizationPrincipal(self, username, password):
+    def getAuthenticatedAuthorizationPrincipal(self, username, password):
         """ Get principal based on a username and password """
         # First try cache.
         #self.logger.debug('Trying username %s from the cache' % username)
@@ -116,7 +101,7 @@ class AuthorizationManager(DmObjectManager):
 #######################################################################
 # Testing.
 if __name__ == '__main__':
-    am = AuthorizationManager.getInstance()
+    am = AuthorizationPrincipalManager.getInstance()
     authPrincipal = am.getAuthorizationPrincipal('sveseli', 'sv')
     print 'Auth principal: ', authPrincipal
 
diff --git a/src/python/dm/common/service/auth/authorizationPrincipalRetriever.py b/src/python/dm/common/service/auth/authorizationPrincipalRetriever.py
new file mode 100755
index 00000000..a7df5826
--- /dev/null
+++ b/src/python/dm/common/service/auth/authorizationPrincipalRetriever.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+
+from dm.common.constants import dmRole
+from dm.common.utility.loggingManager import LoggingManager
+
+class AuthorizationPrincipalRetriever:
+
+    def __init__(self, name=None):
+        self.adminRoleName = dmRole.DM_ADMIN_ROLE
+        self.name = name
+        self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
+
+    def getName(self):
+        return self.name
+
+    def setAdminRoleName(self, adminRoleName):
+        self.adminRoleName = adminRoleName
+
+    def getAuthorizationPrincipal(self, username):
+        return None
+
+    def checkAutorizationPrincipalRole(self, principal):
+        if principal is None or self.adminRoleName is None:
+            return
+        userInfo = principal.getUserInfo()
+        if userInfo is None:
+            return
+        for userSystemRoleName in user.get('userSystemRoleNameList', []):
+            if userSystemRoleName == self.adminRoleName:
+                principal.setRole(dmRole.DM_ADMIN_ROLE)
+
+#######################################################################
+# Testing.
+if __name__ == '__main__':
+    pass
+
diff --git a/src/python/dm/common/service/impl/cryptedPasswordPrincipalAuthenticator.py b/src/python/dm/common/service/auth/cryptedPasswordPrincipalAuthenticator.py
similarity index 100%
rename from src/python/dm/common/service/impl/cryptedPasswordPrincipalAuthenticator.py
rename to src/python/dm/common/service/auth/cryptedPasswordPrincipalAuthenticator.py
diff --git a/src/python/dm/common/service/impl/dbPrincipalRetriever.py b/src/python/dm/common/service/auth/dbPrincipalRetriever.py
similarity index 74%
rename from src/python/dm/common/service/impl/dbPrincipalRetriever.py
rename to src/python/dm/common/service/auth/dbPrincipalRetriever.py
index 6d887a9c..4450f6e1 100755
--- a/src/python/dm/common/service/impl/dbPrincipalRetriever.py
+++ b/src/python/dm/common/service/auth/dbPrincipalRetriever.py
@@ -15,13 +15,10 @@ class DbPrincipalRetriever(AuthorizationPrincipalRetriever):
         principal = None
         try:
             user = self.dbApi.getUserWithPasswordByUsername(username)
-            principal = AuthorizationPrincipal(username, user.get('password'))
+            principal = AuthorizationPrincipal(name=username, token=user.get('password'))
             principal.setRole(dmRole.DM_USER_ROLE)
             principal.setUserInfo(user)
-            if self.adminGroupName is not None:
-                for userGroup in user.get('userGroupList', []):
-                    if userGroup.get('name') == self.adminGroupName:
-                        principal.setRole(dmRole.DM_ADMIN_ROLE)
+            self.checkAutorizationPrincipalRole(principal)
         except Exception, ex:
             self.logger.debug(ex)
         return principal
diff --git a/src/python/dm/common/service/impl/ldapPasswordPrincipalAuthenticator.py b/src/python/dm/common/service/auth/ldapPasswordPrincipalAuthenticator.py
similarity index 100%
rename from src/python/dm/common/service/impl/ldapPasswordPrincipalAuthenticator.py
rename to src/python/dm/common/service/auth/ldapPasswordPrincipalAuthenticator.py
diff --git a/src/python/dm/common/service/impl/noOpPrincipalRetriever.py b/src/python/dm/common/service/auth/noOpPrincipalRetriever.py
similarity index 82%
rename from src/python/dm/common/service/impl/noOpPrincipalRetriever.py
rename to src/python/dm/common/service/auth/noOpPrincipalRetriever.py
index aafef13f..d285e6ee 100755
--- a/src/python/dm/common/service/impl/noOpPrincipalRetriever.py
+++ b/src/python/dm/common/service/auth/noOpPrincipalRetriever.py
@@ -11,10 +11,11 @@ class NoOpPrincipalRetriever(AuthorizationPrincipalRetriever):
         AuthorizationPrincipalRetriever.__init__(self, self.__class__.__name__)
 
     def getAuthorizationPrincipal(self, username):
+        # Set password to be the same as username
         noOpPassword = CryptUtility.cryptPasswordWithPbkdf2(username)
-        principal = AuthorizationPrincipal(username, noOpPassword)
+        principal = AuthorizationPrincipal(name=username, token=noOpPassword)
         principal.setRole(dmRole.DM_USER_ROLE)
-        if self.adminGroupName is not None:
+        if self.adminRoleName is not None:
             principal.setRole(dmRole.DM_ADMIN_ROLE)
         return principal
 
diff --git a/src/python/dm/common/service/impl/authorizationPrincipalRetriever.py b/src/python/dm/common/service/impl/authorizationPrincipalRetriever.py
deleted file mode 100755
index 935dabd6..00000000
--- a/src/python/dm/common/service/impl/authorizationPrincipalRetriever.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python
-
-from dm.common.utility.loggingManager import LoggingManager
-
-class AuthorizationPrincipalRetriever:
-
-    def __init__(self, name=None):
-        self.adminGroupName = None
-        self.name = name
-        self.logger = LoggingManager.getInstance().getLogger(self.__class__.__name__)
-
-    def getName(self):
-        return self.name
-
-    def setAdminGroupName(self, adminGroupName):
-        self.adminGroupName = adminGroupName
-
-    def getAuthorizationPrincipal(self, username):
-        return None
-
-#######################################################################
-# Testing.
-if __name__ == '__main__':
-    pass
-
-- 
GitLab