예제 #1
0
def odnoklassniki_api(data, api_url, public_key, client_secret,
                      request_type='oauth'):
    ''' Calls Odnoklassniki REST API method
        http://dev.odnoklassniki.ru/wiki/display/ok/Odnoklassniki+Rest+API
    '''
    data.update({
        'application_key': public_key,
        'format': 'JSON'
    })
    if request_type == 'oauth':
        data['sig'] = odnoklassniki_oauth_sig(data, client_secret)
    elif request_type == 'iframe_session':
        data['sig'] = odnoklassniki_iframe_sig(data,
                                               data['session_secret_key'])
    elif request_type == 'iframe_nosession':
        data['sig'] = odnoklassniki_iframe_sig(data, client_secret)
    else:
        msg = 'Unknown request type {0}. How should it be signed?'
        raise AuthFailed(msg.format(request_type))
    params = urlencode(data)
    request = Request('{0}fb.do?{1}'.format(api_url, params))
    try:
        return simplejson.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
예제 #2
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 = simplejson.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 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 = simplejson.loads(dsa_urlopen(request).read())
        except HTTPError, e:
            if e.code == 400:
                raise AuthCanceled(self)
            else:
                raise
예제 #4
0
    def auth_complete(self, request, user, *args, **kwargs):
        form = OdnoklassnikiIframeForm(auth=self, data=request.GET)
        if not form.is_valid():
            raise AuthFailed('Cannot authorize: malformed parameters')
        else:
            response = form.get_response()
            extra_user_data = backend_setting(
                self, 'ODNOKLASSNIKI_APP_EXTRA_USER_DATA_LIST', ())
            base_fields = ('uid', 'first_name', 'last_name', 'name')
            fields = base_fields + extra_user_data
            data = {
                'method': 'users.getInfo',
                'uids': '{0}'.format(response['logged_user_id']),
                'fields': ','.join(fields),
            }
            client_key, client_secret, public_key = self.get_settings()
            details = odnoklassniki_api(data, response['api_server'],
                                        public_key, client_secret,
                                        'iframe_nosession')
            if len(details) == 1 and 'uid' in details[0]:
                details = details[0]
                auth_data_fields = backend_setting(
                    self,
                    'ODNOKLASSNIKI_APP_EXTRA_AUTH_DATA_LIST',
                    ('api_server', 'apiconnection', 'session_key',
                     'session_secret_key', 'authorized')
                )

                for field in auth_data_fields:
                    details[field] = response[field]
                details['extra_data_list'] = fields + auth_data_fields
                kwargs.update({
                    'auth': self,
                    'response': details,
                    self.AUTH_BACKEND.name: True
                })
            else:
                raise AuthFailed('Cannot get user details: API error')
        return authenticate(*args, **kwargs)
예제 #5
0
def validate_whitelists(backend, email):
    """
    Validates allowed domains and emails against the following settings:
        GOOGLE_WHITE_LISTED_DOMAINS
        GOOGLE_WHITE_LISTED_EMAILS

    All domains and emails are allowed if setting is an empty list.
    """
    emails = setting('GOOGLE_WHITE_LISTED_EMAILS', [])
    domains = setting('GOOGLE_WHITE_LISTED_DOMAINS', [])
    if emails and email in emails:
        return  # you're good
    if domains and email.split('@', 1)[1] not in domains:
        raise AuthFailed(backend, 'Domain not allowed')
예제 #6
0
 def auth_complete(self, *args, **kwargs):
     """Complete auth process"""
     response = self.consumer().complete(dict(self.data.items()),
                                         self.build_absolute_uri())
     if not response:
         raise AuthException(self, 'OpenID relying party endpoint')
     elif response.status == SUCCESS:
         kwargs.update({
             'auth': self,
             'response': response,
             self.AUTH_BACKEND.name: True
         })
         return authenticate(*args, **kwargs)
     elif response.status == FAILURE:
         raise AuthFailed(self, response.message)
     elif response.status == CANCEL:
         raise AuthCanceled(self)
     else:
         raise AuthUnknownError(self, response.status)
예제 #7
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 = cgi.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)
예제 #8
0
        request = Request(self.ACCESS_TOKEN_URL, data=urlencode(params),
                          headers=headers)

        try:
            response = simplejson.loads(dsa_urlopen(request).read())
        except HTTPError, e:
            if e.code == 400:
                raise AuthCanceled(self)
            else:
                raise
        except (ValueError, KeyError):
            raise AuthUnknownError(self)

        if response.get('error'):
            error = response.get('error_description') or response.get('error')
            raise AuthFailed(self, error)
        else:
            data = self.user_data(response['access_token'], response)
            response.update(data or {})
            kwargs.update({
                'auth': self,
                'response': response,
                self.AUTH_BACKEND.name: True
            })
            return authenticate(*args, **kwargs)

    def get_scope(self):
        """Return list with needed access scope"""
        scope = self.DEFAULT_SCOPE or []
        if self.SCOPE_VAR_NAME:
            scope = scope + setting(self.SCOPE_VAR_NAME, [])