Example #1
0
    async def fetch_access_token(self, code, request_handler):
        body = urllib_parse.urlencode({
            'redirect_uri':
            get_path_for_redirect(request_handler),
            'code':
            code,
            'client_id':
            self.client_id,
            'client_secret':
            self.secret,
            'grant_type':
            'authorization_code',
        })
        http_client = httpclient.AsyncHTTPClient()
        response = await http_client.fetch(
            self.oauth_token_url,
            method='POST',
            headers={'Content-Type': 'application/x-www-form-urlencoded'},
            body=body,
            raise_error=False)

        response_values = {}
        if response.body:
            response_values = escape.json_decode(response.body)

        if response.error:
            if response_values.get('error_description'):
                error_text = response_values.get('error_description')
            elif response_values.get('error'):
                error_text = response_values.get('error')
            else:
                error_text = str(response.error)

            error_message = 'Failed to load access_token: ' + error_text
            LOGGER.error(error_message)
            raise AuthFailureError(error_message)

        response_values = escape.json_decode(response.body)
        access_token = response_values.get('access_token')

        if not access_token:
            message = 'No access token in response: ' + str(response.body)
            LOGGER.error(message)
            raise AuthFailureError(message)

        return access_token
Example #2
0
    async def fetch_user_groups(self, access_token):
        user = self.user_tokens[access_token]

        if user in self.failing_groups_loading:
            raise AuthFailureError('Emulate group loading error')

        if user in self.user_groups:
            return self.user_groups[user]
        return []
Example #3
0
    async def authenticate(self, request_handler):
        code = request_handler.get_argument('code', False)

        if not code:
            LOGGER.error('Code is not specified')
            raise AuthBadRequestException(
                'Missing authorization information. Please contact your administrator'
            )

        access_token = await self.fetch_access_token(code, request_handler)
        user_info = await self.fetch_user_info(access_token)

        user_email = user_info.email
        if not user_email:
            error_message = 'No email field in user response. The response: ' + str(
                user_info.oauth_response)
            LOGGER.error(error_message)
            raise AuthFailureError(error_message)

        if not user_info.enabled:
            error_message = 'User %s is not enabled in OAuth provider. The response: %s' \
                            % (user_email, str(user_info.oauth_response))
            LOGGER.error(error_message)
            raise AuthFailureError(error_message)

        user_state = _UserState(user_email)
        self._users[user_email] = user_state

        if self.group_support:
            user_groups = await self.fetch_user_groups(access_token)
            LOGGER.info('Loaded groups for ' + user_email + ': ' +
                        str(user_groups))
            user_state.groups = user_groups

        now = time.time()

        if self.auth_info_ttl:
            request_handler.set_secure_cookie('token', access_token)
            user_state.last_auth_update = now

        user_state.last_visit = now

        return user_email
def get_path_for_redirect(request_handler):
    referer = request_handler.request.headers.get('Referer')
    if not referer:
        LOGGER.error('No referer')
        raise AuthFailureError('Missing request header. Please contact system administrator')

    parse_result = urllib_parse.urlparse(referer)
    protocol = parse_result[0]
    host = parse_result[1]
    path = parse_result[2]

    return urllib_parse.urlunparse((protocol, host, path, '', '', ''))
    def read_user(self, code, request_handler):
        access_token = yield self.get_access_token(code, request_handler)

        oauth_mixin = tornado.auth.GoogleOAuth2Mixin()
        user_future = oauth_mixin.oauth2_request(
            tornado.auth.GoogleOAuth2Mixin._OAUTH_USERINFO_URL,
            access_token=access_token)
        user_response = yield user_future

        if user_response.get('email'):
            return user_response.get('email')

        error_message = 'No email field in user response. The response: ' + str(user_response)
        LOGGER.error(error_message)
        raise AuthFailureError(error_message)