class AuthFactory: """ An factory for authentication backends. """ _logger = None _config = None _auth_cache = {} _backends = {} def __init__(self): """ Constructor. """ # Initialize stuff. self._config = NipapConfig() self._logger = logging.getLogger(self.__class__.__name__) self._init_backends() def _init_backends(self): """ Initialize auth backends. """ # fetch auth backends from config file self._backends = {} for section in self._config.sections(): # does the section define an auth backend? section_components = section.rsplit('.', 1) if section_components[0] == 'auth.backends': auth_backend = section_components[1] self._backends[auth_backend] = eval(self._config.get(section, 'type')) self._logger.debug("Registered auth backends %s" % str(self._backends)) def reload(self): """ Reload AuthFactory. """ self._auth_cache = {} self._init_backends() def get_auth(self, username, password, authoritative_source, auth_options=None): """ Returns an authentication object. Examines the auth backend given after the '@' in the username and returns a suitable instance of a subclass of the BaseAuth class. * `username` [string] Username to authenticate as. * `password` [string] Password to authenticate with. * `authoritative_source` [string] Authoritative source of the query. * `auth_options` [dict] A dict which, if authenticated as a trusted user, can override `username` and `authoritative_source`. """ if auth_options is None: auth_options = {} # validate arguments if (authoritative_source is None): raise AuthError("Missing authoritative_source.") # remove invalid cache entries rem = list() for key in self._auth_cache: if self._auth_cache[key]['valid_until'] < datetime.utcnow(): rem.append(key) for key in rem: del(self._auth_cache[key]) user_authbackend = username.rsplit('@', 1) # Find out what auth backend to use. # If no auth backend was specified in username, use default backend = "" if len(user_authbackend) == 1: backend = self._config.get('auth', 'default_backend') self._logger.debug("Using default auth backend %s" % backend) else: backend = user_authbackend[1] # do we have a cached instance? auth_str = ( str(username) + str(password) + str(authoritative_source) + str(auth_options) ) if auth_str in self._auth_cache: self._logger.debug('found cached auth object for user %s' % username) return self._auth_cache[auth_str]['auth_object'] # Create auth object try: auth = self._backends[backend](backend, user_authbackend[0], password, authoritative_source, auth_options) except KeyError: raise AuthError("Invalid auth backend '%s' specified" % str(backend)) # save auth object to cache self._auth_cache[auth_str] = { 'valid_until': datetime.utcnow() + timedelta(seconds=self._config.getint('auth', 'auth_cache_timeout')), 'auth_object': auth } return auth
class AuthFactory: """ An factory for authentication backends. """ _logger = None _config = None _auth_cache = {} _backends = {} def __init__(self): """ Constructor. """ # Initialize stuff. self._config = NipapConfig() self._logger = logging.getLogger(self.__class__.__name__) self._init_backends() def _init_backends(self): """ Initialize auth backends. """ # fetch auth backends from config file self._backends = {} for section in self._config.sections(): # does the section define an auth backend? section_components = section.rsplit('.', 1) if section_components[0] == 'auth.backends': auth_backend = section_components[1] self._backends[auth_backend] = eval( self._config.get(section, 'type')) self._logger.debug("Registered auth backends %s" % str(self._backends)) def reload(self): """ Reload AuthFactory. """ self._auth_cache = {} self._init_backends() def get_auth(self, username, password, authoritative_source, auth_options=None): """ Returns an authentication object. Examines the auth backend given after the '@' in the username and returns a suitable instance of a subclass of the BaseAuth class. * `username` [string] Username to authenticate as. * `password` [string] Password to authenticate with. * `authoritative_source` [string] Authoritative source of the query. * `auth_options` [dict] A dict which, if authenticated as a trusted user, can override `username` and `authoritative_source`. """ if auth_options is None: auth_options = {} # validate arguments if (authoritative_source is None): raise AuthError("Missing authoritative_source.") # remove invalid cache entries rem = list() for key in self._auth_cache: if self._auth_cache[key]['valid_until'] < datetime.utcnow(): rem.append(key) for key in rem: del (self._auth_cache[key]) user_authbackend = username.rsplit('@', 1) # Find out what auth backend to use. # If no auth backend was specified in username, use default backend = "" if len(user_authbackend) == 1: backend = self._config.get('auth', 'default_backend') self._logger.debug("Using default auth backend %s" % backend) else: backend = user_authbackend[1] # do we have a cached instance? auth_str = (str(username) + str(password) + str(authoritative_source) + str(auth_options)) if auth_str in self._auth_cache: self._logger.debug('found cached auth object for user %s' % username) return self._auth_cache[auth_str]['auth_object'] # Create auth object try: auth = self._backends[backend](backend, user_authbackend[0], password, authoritative_source, auth_options) except KeyError: raise AuthError("Invalid auth backend '%s' specified" % str(backend)) # save auth object to cache self._auth_cache[auth_str] = { 'valid_until': datetime.utcnow() + timedelta( seconds=self._config.getint('auth', 'auth_cache_timeout')), 'auth_object': auth } return auth