Пример #1
0
    def auth_complete(self, *args, **kwargs):
        """Completes loging process, must return user instance"""
        if self.data.get('error'):
            error = self.data.get('error_description') or self.data['error']
            raise AuthFailed(self, error)

        state = self.validate_state()
        client_id, client_secret = self.get_key_and_secret()
        params = {
            'grant_type': 'authorization_code',  # request auth code
            'code': self.data.get('code', ''),  # server response code
            'client_id': client_id,
            'client_secret': client_secret,
            'redirect_uri': self.get_redirect_uri(state)
        }
        headers = {'Content-Type': 'application/x-www-form-urlencoded',
                    'Accept': 'application/json'}
        request = Request(self.ACCESS_TOKEN_URL, data=urlencode(params),
                          headers=headers)

        try:
            response = json.loads(dsa_urlopen(request).read())
        except HTTPError, e:
            if e.code == 400:
                raise AuthCanceled(self)
            else:
                raise
Пример #2
0
    def auth_complete(self, *args, **kwargs):
        """Completes logging process, must return user instance"""
        if not 'assertion' in self.data:
            raise AuthMissingParameter(self, 'assertion')

        data = urlencode({
            'assertion': self.data['assertion'],
            'audience': self.request.get_host()
        })

        try:
            response = json.load(dsa_urlopen(BROWSER_ID_SERVER, data=data))
        except ValueError:
            log('error',
                'Could not load user data from BrowserID.',
                exc_info=True)
        else:
            if response.get('status') == 'failure':
                log('debug', 'Authentication failed.')
                raise AuthFailed(self)

            kwargs.update({
                'auth': self,
                'response': response,
                self.AUTH_BACKEND.name: True
            })
            return authenticate(*args, **kwargs)
Пример #3
0
    def auth_complete(self, *args, **kwargs):
        """Completes loging process, must return user instance"""
        if not 'assertion' in self.data:
            raise AuthMissingParameter(self, 'assertion')

        data = urlencode({
            'assertion': self.data['assertion'],
            'audience': self.request.get_host()
        })

        try:
            response = json.load(dsa_urlopen(BROWSER_ID_SERVER, data=data))
        except ValueError:
            log('error', 'Could not load user data from BrowserID.',
                exc_info=True)
        else:
            if response.get('status') == 'failure':
                log('debug', 'Authentication failed.')
                raise AuthFailed(self)

            kwargs.update({
                'auth': self,
                'response': response,
                self.AUTH_BACKEND.name: True
            })
            return authenticate(*args, **kwargs)
Пример #4
0
def vkontakte_api(method, data):
    """Calls VKontakte OpenAPI method
        http://vkontakte.ru/apiclub,
        http://vkontakte.ru/pages.php?o=-1&p=%C2%FB%EF%EE%EB%ED%E5%ED%E8%E5%20
                                             %E7%E0%EF%F0%EE%F1%EE%E2%20%EA%20
                                             API
    """

    # We need to perform server-side call if no access_token
    if not 'access_token' in data:
        if not 'v' in data:
            data['v'] = VKONTAKTE_API_VERSION

        if not 'api_id' in data:
            data['api_id'] = _api_get_val_fun('id', 'VKONTAKTE_APP_ID')

        data['method'] = method
        data['format'] = 'json'

        url = VKONTAKTE_SERVER_API_URL
        secret = _api_get_val_fun('key', 'VKONTAKTE_APP_SECRET')

        param_list = sorted(list(item + '=' + data[item] for item in data))
        data['sig'] = md5(''.join(param_list) + secret).hexdigest()
    else:
        url = VKONTAKTE_API_URL + method

    params = urlencode(data)
    url += '?' + params
    try:
        return json.load(dsa_urlopen(url))
    except (TypeError, KeyError, IOError, ValueError, IndexError):
        log('error', 'Could not load data from VKontakte.',
            exc_info=True, extra=dict(data=data))
        return None
Пример #5
0
def mixcloud_profile(access_token):
    data = {'access_token': access_token, 'alt': 'json'}
    request = Request(MIXCLOUD_PROFILE_URL + '?' + urlencode(data))
    try:
        return json.loads(dsa_urlopen(request).read())
    except (ValueError, KeyError, IOError):
        return None
Пример #6
0
def vkontakte_api(method, data):
    """Calls VKontakte OpenAPI method
        http://vkontakte.ru/apiclub,
        http://vkontakte.ru/pages.php?o=-1&p=%C2%FB%EF%EE%EB%ED%E5%ED%E8%E5%20
                                             %E7%E0%EF%F0%EE%F1%EE%E2%20%EA%20
                                             API
    """

    # We need to perform server-side call if no access_token
    if not "access_token" in data:
        if not "v" in data:
            data["v"] = VKONTAKTE_API_VERSION

        if not "api_id" in data:
            data["api_id"] = _api_get_val_fun("id", "VKONTAKTE_APP_ID")

        data["method"] = method
        data["format"] = "json"

        url = VKONTAKTE_SERVER_API_URL
        secret = _api_get_val_fun("key", "VKONTAKTE_APP_SECRET")

        param_list = sorted(list(item + "=" + data[item] for item in data))
        data["sig"] = md5("".join(param_list) + secret).hexdigest()
    else:
        url = VKONTAKTE_API_URL + method

    params = urlencode(data)
    url += "?" + params
    try:
        return json.load(dsa_urlopen(url))
    except (TypeError, KeyError, IOError, ValueError, IndexError):
        log("error", "Could not load data from VKontakte.", exc_info=True, extra=dict(data=data))
        return None
Пример #7
0
def mixcloud_profile(access_token):
    data = {'access_token': access_token, 'alt': 'json'}
    request = Request(MIXCLOUD_PROFILE_URL + '?' + urlencode(data))
    try:
        return json.loads(dsa_urlopen(request).read())
    except (ValueError, KeyError, IOError):
        return None
Пример #8
0
    def auth_complete(self, *args, **kwargs):
        """Completes logging process, must return user instance"""
        if self.data.get('error'):
            error = self.data.get('error_description') or self.data['error']
            raise AuthFailed(self, error)

        state = self.validate_state()
        client_id, client_secret = self.get_key_and_secret()
        params = {
            'grant_type': 'authorization_code',  # request auth code
            'code': self.data.get('code', ''),  # server response code
            'client_id': client_id,
            'client_secret': client_secret,
            'redirect_uri': self.get_redirect_uri(state)
        }
        headers = {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Accept': 'application/json'
        }
        request = Request(self.ACCESS_TOKEN_URL,
                          data=urlencode(params),
                          headers=headers)

        try:
            response = json.loads(dsa_urlopen(request).read())
        except HTTPError, e:
            if e.code == 400:
                raise AuthCanceled(self)
            else:
                raise
Пример #9
0
    def auth_complete(self, *args, **kwargs):
        """Completes logging process, must return user instance"""
        if self.data.get("error"):
            error = self.data.get("error_description") or self.data["error"]
            raise AuthFailed(self, error)

        state = self.validate_state()
        client_id, client_secret = self.get_key_and_secret()
        params = {
            "grant_type": "authorization_code",  # request auth code
            "code": self.data.get("code", ""),  # server response code
            "client_id": client_id,
            "client_secret": client_secret,
            "redirect_uri": self.get_redirect_uri(state),
        }
        headers = {"Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json"}
        request = Request(self.ACCESS_TOKEN_URL, data=urlencode(params), headers=headers)

        try:
            response = json.loads(dsa_urlopen(request).read())
        except HTTPError, e:
            if e.code == 400:
                raise AuthCanceled(self)
            else:
                raise
Пример #10
0
 def user_data(self, access_token, *args, **kwargs):
     """Loads user data from service"""
     params = {'oauth_token': access_token}
     url = FOURSQUARE_CHECK_AUTH + '?' + urlencode(params)
     try:
         return json.load(dsa_urlopen(url))
     except ValueError:
         return None
Пример #11
0
 def user_data(self, access_token, *args, **kwargs):
     uid = args[0]['uid']
     data = {'access_token': access_token, 'uid': uid}
     url = 'https://api.weibo.com/2/users/show.json?' + urlencode(data)
     try:
         return json.loads(dsa_urlopen(url).read())
     except (ValueError, KeyError, IOError):
         return None
Пример #12
0
 def user_data(self, access_token, *args, **kwargs):
     """Loads user data from service"""
     url = GITHUB_USER_DATA_URL + '?' + urlencode(
         {'access_token': access_token})
     try:
         return json.load(dsa_urlopen(url))
     except ValueError:
         return None
Пример #13
0
 def user_data(self, access_token, *args, **kwargs):
     """Loads user data from service"""
     url = LIVE_USER_DATA_URL + '?' + urlencode(
         {'access_token': access_token})
     try:
         return json.load(dsa_urlopen(url))
     except (ValueError, IOError):
         raise AuthUnknownError(
             'Error during profile retrieval, please, try again later')
Пример #14
0
 def user_data(self, access_token, *args, **kwargs):
     """Loads user data from service"""
     url = GITHUB_USER_DATA_URL + '?' + urlencode({
         'access_token': access_token
     })
     try:
         return json.load(dsa_urlopen(url))
     except ValueError:
         return None
Пример #15
0
 def user_data(self, access_token, *args, **kwargs):
     """Loads user data from service"""
     url = LIVE_USER_DATA_URL + '?' + urlencode({
         'access_token': access_token
     })
     try:
         return json.load(dsa_urlopen(url))
     except (ValueError, IOError):
         raise AuthUnknownError('Error during profile retrieval, please, try again later')
Пример #16
0
def googleapis_profile(url, access_token):
    """
    Loads user data from googleapis service, such as name, given_name,
    family_name, etc. as it's described in:
    https://developers.google.com/accounts/docs/OAuth2Login
    """
    data = {'access_token': access_token, 'alt': 'json'}
    request = Request(url + '?' + urlencode(data))
    try:
        return json.loads(dsa_urlopen(request).read())
    except (ValueError, KeyError, IOError):
        return None
Пример #17
0
def googleapis_profile(url, access_token):
    """
    Loads user data from googleapis service, such as name, given_name,
    family_name, etc. as it's described in:
    https://developers.google.com/accounts/docs/OAuth2Login
    """
    data = {'access_token': access_token, 'alt': 'json'}
    request = Request(url + '?' + urlencode(data))
    try:
        return json.loads(dsa_urlopen(request).read())
    except (ValueError, KeyError, IOError):
        return None
Пример #18
0
def googleapis_email(url, params):
    """Loads user data from googleapis service, only email so far as it's
    described in http://sites.google.com/site/oauthgoog/Home/emaildisplayscope

    Parameters must be passed in queryset and Authorization header as described
    on Google OAuth documentation at:
    http://groups.google.com/group/oauth/browse_thread/thread/d15add9beb418ebc
    and: http://code.google.com/apis/accounts/docs/OAuth2.html#CallingAnAPI
    """
    request = Request(url + '?' + params, headers={'Authorization': params})
    try:
        return json.loads(dsa_urlopen(request).read())['data']
    except (ValueError, KeyError, IOError):
        return None
Пример #19
0
def googleapis_email(url, params):
    """Loads user data from googleapis service, only email so far as it's
    described in http://sites.google.com/site/oauthgoog/Home/emaildisplayscope

    Parameters must be passed in queryset and Authorization header as described
    on Google OAuth documentation at:
    http://groups.google.com/group/oauth/browse_thread/thread/d15add9beb418ebc
    and: http://code.google.com/apis/accounts/docs/OAuth2.html#CallingAnAPI
    """
    request = Request(url + '?' + params, headers={'Authorization': params})
    try:
        return json.loads(dsa_urlopen(request).read())['data']
    except (ValueError, KeyError, IOError):
        return None
Пример #20
0
    def user_data(self, access_token, response, *args, **kwargs):
        """Loads user data from service"""
        params = {'oauth_token': access_token,
                  'format': 'json',
                  'text': 1,
                  }

        url = self.get_api_url() + '?' + urlencode(params)
        try:
            return json.load(dsa_urlopen(url))
        except (ValueError, IndexError):
            log('error', 'Could not load data from Yandex.',
                exc_info=True, extra=dict(data=params))
            return None
Пример #21
0
def mailru_api(data):
    """ Calls Mail.ru REST API method
        http://api.mail.ru/docs/guides/restapi/
    """
    data.update({'app_id': settings.MAILRU_OAUTH2_CLIENT_KEY, 'secure': '1'})
    data['sig'] = mailru_sig(data)

    params = urlencode(data)
    request = Request(MAILRU_API_URL, params)
    try:
        return json.loads(dsa_urlopen(request).read())
    except (TypeError, KeyError, IOError, ValueError, IndexError):
        log('error', 'Could not load data from Mail.ru.',
            exc_info=True, extra=dict(data=params))
        return None
Пример #22
0
    def user_data(self, access_token, response, *args, **kwargs):
        """Loads user data from service"""
        params = {
            'oauth_token': access_token,
            'format': 'json',
            'text': 1,
        }

        url = self.get_api_url() + '?' + urlencode(params)
        try:
            return json.load(dsa_urlopen(url))
        except (ValueError, IndexError):
            log('error',
                'Could not load data from Yandex.',
                exc_info=True,
                extra=dict(data=params))
            return None
Пример #23
0
def mailru_api(data):
    """ Calls Mail.ru REST API method
        http://api.mail.ru/docs/guides/restapi/
    """
    data.update({'app_id': settings.MAILRU_OAUTH2_CLIENT_KEY, 'secure': '1'})
    data['sig'] = mailru_sig(data)

    params = urlencode(data)
    request = Request(MAILRU_API_URL, params)
    try:
        return json.loads(dsa_urlopen(request).read())
    except (TypeError, KeyError, IOError, ValueError, IndexError):
        log('error',
            'Could not load data from Mail.ru.',
            exc_info=True,
            extra=dict(data=params))
        return None
Пример #24
0
def odnoklassniki_api(data):
    """ Calls Odnoklassniki REST API method
        http://dev.odnoklassniki.ru/wiki/display/ok/Odnoklassniki+Rest+API
    """
    data.update({
        'application_key': settings.ODNOKLASSNIKI_OAUTH2_APP_KEY,
        'format': 'JSON'
    })
    data['sig'] = odnoklassniki_sig(data)

    params = urlencode(data)
    request = Request(ODNOKLASSNIKI_API_URL + '?' + params)
    try:
        return json.loads(dsa_urlopen(request).read())
    except (TypeError, KeyError, IOError, ValueError, IndexError):
        log('error', 'Could not load data from Odnoklassniki.',
            exc_info=True, extra=dict(data=params))
        return None
Пример #25
0
def odnoklassniki_api(data):
    """ Calls Odnoklassniki REST API method
        http://dev.odnoklassniki.ru/wiki/display/ok/Odnoklassniki+Rest+API
    """
    data.update({
        'application_key': settings.ODNOKLASSNIKI_OAUTH2_APP_KEY,
        'format': 'JSON'
    })
    data['sig'] = odnoklassniki_sig(data)

    params = urlencode(data)
    request = Request(ODNOKLASSNIKI_API_URL + '?' + params)
    try:
        return json.loads(dsa_urlopen(request).read())
    except (TypeError, KeyError, IOError, ValueError, IndexError):
        log('error',
            'Could not load data from Odnoklassniki.',
            exc_info=True,
            extra=dict(data=params))
        return None
Пример #26
0
 def user_data(self, access_token, *args, **kwargs):
     """Loads user data from Orkut service"""
     fields = ORKUT_DEFAULT_DATA
     if setting("ORKUT_EXTRA_DATA"):
         fields += "," + setting("ORKUT_EXTRA_DATA")
     scope = ORKUT_SCOPE + setting("ORKUT_EXTRA_SCOPE", [])
     params = {
         "method": "people.get",
         "id": "myself",
         "userId": "@me",
         "groupId": "@self",
         "fields": fields,
         "scope": " ".join(scope),
     }
     request = self.oauth_request(access_token, ORKUT_REST_ENDPOINT, params)
     response = dsa_urlopen(request.to_url()).read()
     try:
         return json.loads(response)["data"]
     except (ValueError, KeyError):
         return None
Пример #27
0
 def user_data(self, access_token, *args, **kwargs):
     """Loads user data from Orkut service"""
     fields = ORKUT_DEFAULT_DATA
     if setting('ORKUT_EXTRA_DATA'):
         fields += ',' + setting('ORKUT_EXTRA_DATA')
     scope = ORKUT_SCOPE + setting('ORKUT_EXTRA_SCOPE', [])
     params = {
         'method': 'people.get',
         'id': 'myself',
         'userId': '@me',
         'groupId': '@self',
         'fields': fields,
         'scope': ' '.join(scope)
     }
     request = self.oauth_request(access_token, ORKUT_REST_ENDPOINT, params)
     response = dsa_urlopen(request.to_url()).read()
     try:
         return json.loads(response)['data']
     except (ValueError, KeyError):
         return None
Пример #28
0
    def user_data(self, access_token, *args, **kwargs):
        """Loads user data from service"""
        data = None
        params = backend_setting(self, self.EXTRA_PARAMS_VAR_NAME, {})
        params['access_token'] = access_token
        url = FACEBOOK_ME + urlencode(params)

        try:
            data = json.load(dsa_urlopen(url))
        except ValueError:
            extra = {'access_token': sanitize_log_data(access_token)}
            log('error', 'Could not load user data from Facebook.',
                exc_info=True, extra=extra)
        except HTTPError:
            extra = {'access_token': sanitize_log_data(access_token)}
            log('error', 'Error validating access token.',
                exc_info=True, extra=extra)
            raise AuthTokenError(self)
        else:
            log('debug', 'Found user data for token %s',
                sanitize_log_data(access_token), extra={'data': data})
        return data
Пример #29
0
    def user_data(self, access_token, *args, **kwargs):
        """Loads user data from service"""
        data = None
        params = backend_setting(self, self.EXTRA_PARAMS_VAR_NAME, {})
        params['access_token'] = access_token
        url = FACEBOOK_ME + urlencode(params)

        try:
            data = json.load(dsa_urlopen(url))
        except ValueError:
            extra = {'access_token': sanitize_log_data(access_token)}
            log('error', 'Could not load user data from Facebook.',
                exc_info=True, extra=extra)
        except HTTPError:
            extra = {'access_token': sanitize_log_data(access_token)}
            log('error', 'Error validating access token.',
                exc_info=True, extra=extra)
            raise AuthTokenError(self)
        else:
            log('debug', 'Found user data for token %s',
                sanitize_log_data(access_token), extra={'data': data})
        return data
Пример #30
0
def vkontakte_api(method, data):
    """Calls VKontakte OpenAPI method
        http://vkontakte.ru/apiclub,
        http://vkontakte.ru/pages.php?o=-1&p=%C2%FB%EF%EE%EB%ED%E5%ED%E8%E5%20
                                             %E7%E0%EF%F0%EE%F1%EE%E2%20%EA%20
                                             API
    """

    # We need to perform server-side call if no access_token
    if not 'access_token' in data:
        if not 'v' in data:
            data['v'] = VKONTAKTE_API_VERSION

        if not 'api_id' in data:
            data['api_id'] = _api_get_val_fun('id', 'VKONTAKTE_APP_ID')

        data['method'] = method
        data['format'] = 'json'

        url = VKONTAKTE_SERVER_API_URL
        secret = _api_get_val_fun('key', 'VKONTAKTE_APP_SECRET')

        param_list = sorted(list(item + '=' + data[item] for item in data))
        data['sig'] = md5(''.join(param_list) + secret).hexdigest()
    else:
        url = VKONTAKTE_API_URL + method

    params = urlencode(data)
    url += '?' + params
    try:
        return json.load(dsa_urlopen(url))
    except (TypeError, KeyError, IOError, ValueError, IndexError):
        log('error',
            'Could not load data from VKontakte.',
            exc_info=True,
            extra=dict(data=data))
        return None
Пример #31
0
 def user_data(self, access_token):
     """Return user data provided"""
     # Bitbucket has a bit of an indirect route to obtain user data from an
     # authenticated query: First obtain the user's email via an
     # authenticated GET
     url = BITBUCKET_EMAIL_DATA_URL
     request = self.oauth_request(access_token, url)
     response = self.fetch_response(request)
     try:
         # Then retrieve the user's primary email address or the top email
         email_addresses = json.loads(response)
         for email_address in reversed(email_addresses):
             if email_address['active']:
                 email = email_address['email']
                 if email_address['primary']:
                     break
         # Then return the user data using a normal GET with the
         # BITBUCKET_USER_DATA_URL and the user's email
         response = dsa_urlopen(BITBUCKET_USER_DATA_URL + email)
         user_details = json.load(response)['user']
         user_details['email'] = email
         return user_details
     except ValueError:
         return None
Пример #32
0
 def user_data(self, access_token):
     """Return user data provided"""
     # Bitbucket has a bit of an indirect route to obtain user data from an
     # authenticated query: First obtain the user's email via an
     # authenticated GET
     url = BITBUCKET_EMAIL_DATA_URL
     request = self.oauth_request(access_token, url)
     response = self.fetch_response(request)
     try:
         # Then retrieve the user's primary email address or the top email
         email_addresses = json.loads(response)
         for email_address in reversed(email_addresses):
             if email_address['active']:
                 email = email_address['email']
                 if email_address['primary']:
                     break
         # Then return the user data using a normal GET with the
         # BITBUCKET_USER_DATA_URL and the user's email
         response = dsa_urlopen(BITBUCKET_USER_DATA_URL + email)
         user_details = json.load(response)['user']
         user_details['email'] = email
         return user_details
     except ValueError:
         return None
Пример #33
0
    def auth_complete(self, *args, **kwargs):
        """Completes logging process, must return user instance"""
        access_token = None
        expires = None

        if 'code' in self.data:
            state = self.validate_state()
            url = ACCESS_TOKEN + urlencode({
                'client_id': backend_setting(self, self.SETTINGS_KEY_NAME),
                'redirect_uri': self.get_redirect_uri(state),
                'client_secret': backend_setting(self,
                                                 self.SETTINGS_SECRET_NAME),
                'code': self.data['code']
            })
            try:
                response = urlparse.parse_qs(dsa_urlopen(url).read())
            except HTTPError:
                raise AuthFailed(self, 'There was an error authenticating the app')

            access_token = response['access_token'][0]
            if 'expires' in response:
                expires = response['expires'][0]

        if 'signed_request' in self.data:
            response = load_signed_request(self.data.get('signed_request'),
                backend_setting(self, self.SETTINGS_SECRET_NAME))

            if response is not None:
                access_token = response.get('access_token') or response.get('oauth_token') or \
                    self.data.get('access_token')

                if 'expires' in response:
                    expires = response['expires']

        if access_token:
            data = self.user_data(access_token)

            if not isinstance(data, dict):
                # From time to time Facebook responds back a JSON with just
                # False as value, the reason is still unknown, but since the
                # data is needed (it contains the user ID used to identify the
                # account on further logins), this app cannot allow it to
                # continue with the auth process.
                raise AuthUnknownError(self, 'An error occurred while retrieving users Facebook data')

            data['access_token'] = access_token
            # expires will not be part of response if offline access
            # permission was requested
            if expires:
                data['expires'] = expires

            kwargs.update({'auth': self,
                           'response': data,
                           self.AUTH_BACKEND.name: True})

            return authenticate(*args, **kwargs)
        else:
            if self.data.get('error') == 'access_denied':
                raise AuthCanceled(self)
            else:
                raise AuthException(self)
Пример #34
0
 def fetch_response(self, request):
     """Executes request and fetchs service response"""
     response = dsa_urlopen(request.to_url())
     return '\n'.join(response.readlines())
Пример #35
0
 def fetch_response(self, request):
     """Executes request and fetched service response"""
     response = dsa_urlopen(request.to_url())
     return '\n'.join(response.readlines())
Пример #36
0
    def auth_complete(self, *args, **kwargs):
        """Completes loging process, must return user instance"""
        access_token = None
        expires = None

        if 'code' in self.data:
            state = self.validate_state()
            url = ACCESS_TOKEN + urlencode({
                'client_id': backend_setting(self, self.SETTINGS_KEY_NAME),
                'redirect_uri': self.get_redirect_uri(state),
                'client_secret': backend_setting(self,
                                                 self.SETTINGS_SECRET_NAME),
                'code': self.data['code']
            })
            try:
                response = urlparse.parse_qs(dsa_urlopen(url).read())
            except HTTPError:
                raise AuthFailed(self, 'There was an error authenticating the app')

            access_token = response['access_token'][0]
            if 'expires' in response:
                expires = response['expires'][0]

        if 'signed_request' in self.data:
            response = load_signed_request(self.data.get('signed_request'),
                backend_setting(self, self.SETTINGS_SECRET_NAME))

            if response is not None:
                access_token = response.get('access_token') or \
                               response.get('oauth_token') or \
                               self.data.get('access_token')

                if 'expires' in response:
                    expires = response['expires']

        if access_token:
            data = self.user_data(access_token)

            if not isinstance(data, dict):
                # From time to time Facebook responds back a JSON with just
                # False as value, the reason is still unknown, but since the
                # data is needed (it contains the user ID used to identify the
                # account on further logins), this app cannot allow it to
                # continue with the auth process.
                raise AuthUnknownError(self, 'An error ocurred while retrieving users Facebook data')

            data['access_token'] = access_token
            # expires will not be part of response if offline access
            # premission was requested
            if expires:
                data['expires'] = expires

            kwargs.update({'auth': self,
                           'response': data,
                           self.AUTH_BACKEND.name: True})

            return authenticate(*args, **kwargs)
        else:
            if self.data.get('error') == 'access_denied':
                raise AuthCanceled(self)
            else:
                raise AuthException(self)