#!/usr/bin/env python import os from dm.common.exceptions.authorizationError import AuthorizationError 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 AuthorizationPrincipalManager(DmObjectManager, Singleton): DEFAULT_CACHE_SIZE = 10000 # number of items DEFAULT_CACHE_OBJECT_LIFETIME = 3600 # seconds CONFIG_SECTION_NAME = 'AuthorizationPrincipalManager' ADMIN_ROLE_NAME_KEY = 'adminrolename' PRINCIPAL_RETRIEVER_KEY = 'principalretriever' PRINCIPAL_AUTHENTICATOR_KEY = 'principalauthenticator' # Singleton instance. __instance = None def __init__(self): if AuthorizationPrincipalManager.__instance: return AuthorizationPrincipalManager.__instance = self DmObjectManager.__init__(self) self.configurationManager = ConfigurationManager.getInstance() self.principalRetriever = None self.principalAuthenticatorList = [] self.objectCache = ObjectCache(AuthorizationPrincipalManager.DEFAULT_CACHE_SIZE, AuthorizationPrincipalManager.DEFAULT_CACHE_OBJECT_LIFETIME) self.configure() @classmethod def cryptPassword(cls, cleartext): return CryptUtility.cryptPassword(cleartext) @classmethod def cryptPasswordWithPbkdf2(cls, cleartext): return CryptUtility.cryptPasswordWithPbkdf2(cleartext) def configure(self): configItems = self.configurationManager.getConfigItems(AuthorizationPrincipalManager.CONFIG_SECTION_NAME) self.logger.debug('Got config items: %s' % configItems) adminRoleName = self.configurationManager.getConfigOption(AuthorizationPrincipalManager.CONFIG_SECTION_NAME, AuthorizationPrincipalManager.ADMIN_ROLE_NAME_KEY) # Create principal retriever 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 = 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(AuthorizationPrincipalManager.PRINCIPAL_AUTHENTICATOR_KEY): (moduleName,className,constructor) = self.configurationManager.getModuleClassConstructorTuple(value, AuthorizationPrincipalManager) self.logger.debug('Creating principal authenticator class: %s' % className) 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 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) principal = None principalTuple = self.objectCache.get(username) if principalTuple is not None: (id, principal, updateTime, expirationTime) = principalTuple if principal is None: # Try principal retriever principal = self.principalRetriever.getAuthorizationPrincipal(username) if principal is None: self.logger.debug('No principal for username: %s' % username) return # Try all authorization principal authenticators. for principalAuthenticator in self.principalAuthenticatorList: self.logger.debug('Attempting to authenticate %s by %s' % (username, principalAuthenticator.getName())) authenticatedPrincipal = principalAuthenticator.authenticatePrincipal(principal, password) if authenticatedPrincipal is not None: self.logger.debug('Adding authorization principal %s to the cache, authenticated by %s' % (principal.getName(),principalAuthenticator.getName())) self.objectCache.put(username, authenticatedPrincipal) return authenticatedPrincipal return None def removeAuthorizationPrincipal(self, username): """ Clear principal from the cache. """ self.objectCache.remove(username) ####################################################################### # Testing. if __name__ == '__main__': am = AuthorizationPrincipalManager.getInstance() authPrincipal = am.getAuthorizationPrincipal('sveseli', 'sv') print 'Auth principal: ', authPrincipal