Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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