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
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)
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
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)
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')
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)
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)
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, [])