def authenticate(self, environ, start_response):
        """
        Implements the authentication logic.

        :param environ: WSGI environment instance.
        :type environ: dict
        :param start_response: WSGI start response callable.
        :type start_response: callable
        :returns: True on success, False on failure
        :rtype: bool
        """
        user, passwd = decode_basic_auth(self.logger,
                                         environ.get('HTTP_AUTHORIZATION'))

        # If there is no user or password then log and don't even bother
        # keystone with a request. Fail early.
        if user is None or passwd is None:
            self.logger.info('Authentication can not continue due to mising '
                             'user/pass. Rejecting.')
            self.logger.debug('User: {}, Pass: {}'.format(user, passwd))
            self.logger.debug('Environ: {}'.format(environ))
            return False

        headers = {'Content-Type': 'application/json'}
        body = {'auth': {'identity': {}}}
        ident = body['auth']['identity']

        ident['methods'] = ['password']
        ident['password'] = {
            'user': {
                'name': user,
                'password': passwd,
                'domain': {
                    'name': self.domain
                }
            }
        }

        try:
            response = requests.post(self.url,
                                     data=json.dumps(body),
                                     headers=headers)
        except requests.exceptions.BaseHTTPError as error:
            self.logger.error(
                'Could not reach {}. Denying access. {}: {}'.format(
                    self.url, type(error), error))
            return False

        subject_token_name = 'X-Subject-Token'
        if subject_token_name in response.headers:
            token = response.headers[subject_token_name]
            start_response('200 OK', [('content-type', 'application/json'),
                                      (subject_token_name, token)])
            return True

        # Forbid by default
        return False
Example #2
0
 def test_decode_basic_auth(self):
     """
     Verify decoding returns a filled tuple given the proper header no matter the case of basic.
     """
     basic = list('basic')
     for x in range(0, 5):
         self.assertEquals(
             ('a', 'a'),
             decode_basic_auth(None, '{0} YTph'.format(''.join(basic))))
         # Update the next letter to be capitalized
         basic[x] = basic[x].capitalize()
    def authenticate(self, environ, start_response):
        """
        Implements the authentication logic.

        :param environ: WSGI environment instance.
        :type environ: dict
        :param start_response: WSGI start response callable.
        :type start_response: callable
        :returns: True on success, False on failure
        :rtype: bool
        """
        user, passwd = decode_basic_auth(self.logger,
                                         environ.get('HTTP_AUTHORIZATION'))
        if user is not None and passwd is not None:
            if user in self._data.keys():
                self.logger.debug('User %s found in datastore.', user)
                if self.check_authentication(user, passwd):
                    return True  # Authentication is good

        # Forbid by default
        return False
Example #4
0
 def test_decode_basic_auth_with_bad_data(self):
     """
     Verify decoding returns no user with bad base64 data in the header.
     """
     self.assertEquals((None, None),
                       decode_basic_auth(None, 'basic BADDATA'))