def process_error(self, data): if data.get('error'): if data['error'] == 'denied' or data['error'] == 'access_denied': raise AuthCanceled(self, data.get('error_description', '')) raise AuthFailed(self, data.get('error_description') or data['error']) elif 'denied' in data: raise AuthCanceled(self, data['denied'])
def force_new_user(backend, user=None, *args, **kwargs): """ Prevent social auth from associating multiple social accounts with the same crimsononline account. """ if user: raise AuthFailed(backend, 'Please log out of admin before attempting a login')
def process_error(self, data): error_code = data.get('errorCode') or \ data.get('statusCode') or \ data.get('error') error_message = data.get('errorMessage') or \ data.get('statusMessage') or \ data.get('error_desciption') if error_code is not None or error_message is not None: raise AuthFailed(self, error_message or error_code)
def process_error(self, data): if not data: raise AuthException(self, 'OpenID relying party endpoint') elif data.status == FAILURE: raise AuthFailed(self, data.message) elif data.status == CANCEL: raise AuthCanceled(self) elif data.status != SUCCESS: raise AuthUnknownError(self, data.status)
def request(self, url, method='GET', *args, **kwargs): kwargs.setdefault('timeout', self.setting('REQUESTS_TIMEOUT') or self.setting('URLOPEN_TIMEOUT')) try: response = request(method, url, *args, **kwargs) except ConnectionError as err: raise AuthFailed(self, str(err)) response.raise_for_status() return response
def user_by_email(backend, details, *args, **kwargs): if backend.name == 'email': if not details.get('email'): raise AuthFailed(backend, 'Missing email') request_data = backend.strategy.request_data() password = request_data.get('password') if not request_data.get('verification_code') and not password: raise AuthFailed(backend, 'Missing password') try: user = User.objects.get(email=details['email']) except User.DoesNotExist: user = None else: if not request_data.get('verification_code') and \ not user.check_password(password): raise AuthFailed(backend, 'Wrong password') return {'user': user, 'password': password}
def get_user_details(self, response): if 'blocked' in response and response['blocked']: raise AuthFailed('User is blocked') return { 'username': response.get('username', ''), 'email': '', 'fullname': response.get('username', ''), 'first_name': response.get('username', ''), 'last_name': '', }
def auth_complete(self, *args, **kwargs): """Completes loging process, must return user instance""" if not 'assertion' in self.data: raise AuthMissingParameter(self, 'assertion') response = self.get_json('https://browserid.org/verify', params={ 'assertion': self.data['assertion'], 'audience': self.strategy.request_host() }) if response.get('status') == 'failure': raise AuthFailed(self) kwargs.update({'response': response, 'backend': self}) return self.strategy.authenticate(*args, **kwargs)
def request(self, url, method='GET', *args, **kwargs): kwargs.setdefault('headers', {}) kwargs.setdefault('timeout', self.setting('REQUESTS_TIMEOUT') or self.setting('URLOPEN_TIMEOUT')) if self.SEND_USER_AGENT and 'User-Agent' not in kwargs['headers']: kwargs['headers']['User-Agent'] = user_agent() try: response = request(method, url, *args, **kwargs) except ConnectionError as err: raise AuthFailed(self, str(err)) response.raise_for_status() return response
def user_data(self, access_token, *args, **kwargs): """Loads user data from service""" user_data = super(GithubMemberOAuth2, self).user_data(access_token, *args, **kwargs) try: self.request(self.member_url(user_data), params={'access_token': access_token}) except HTTPError as err: # if the user is a member of the organization, response code # will be 204, see http://bit.ly/ZS6vFl if err.response.status_code != 204: raise AuthFailed(self, 'User doesn\'t belong to the organization') return user_data
def user_data(self, access_token, *args, **kwargs): """Loads user data from service""" user_data = super(GithubOrganizationOAuth2, self).user_data(access_token, *args, **kwargs) url = 'https://api.github.com/orgs/{org}/members/{username}'\ .format(org=self.setting('NAME'), username=user_data.get('login')) try: self.request(url, params={'access_token': access_token}) except HTTPError as err: # if the user is a member of the organization, response code # will be 204, see http://bit.ly/ZS6vFl if err.response.status_code != 204: raise AuthFailed('User doesn\'t belong to the organization') return user_data
def auth_complete(self, *args, **kwargs): """ The user has been redirected back from the third party and we should now log them in, if everything checks out. """ if not DummyBackend.SUCCEED: raise AuthFailed(self, 'Third Party login failed.') response = { 'dummy': True, } kwargs.update({'response': response, 'backend': self}) return self.strategy.authenticate(*args, **kwargs)
def start(self): """ Prepare to handle a login request. This method replaces social.actions.do_auth and must be kept in sync with any upstream changes in that method. In the current version of the upstream, this means replacing the logic to populate the session from request parameters, and not calling backend.start() to avoid an unwanted redirect to the non-existent login page. """ # Clean any partial pipeline data self.strategy.clean_partial_pipeline() # Save validated LTI parameters (or None if invalid or not submitted) validated_lti_params = self.get_validated_lti_params(self.strategy) # Set a auth_entry here so we don't have to receive that as a custom parameter self.strategy.session_setdefault('auth_entry', 'login') if not validated_lti_params: self.strategy.session_set(LTI_PARAMS_KEY, None) raise AuthFailed(self, "LTI parameters could not be validated.") else: self.strategy.session_set(LTI_PARAMS_KEY, validated_lti_params) # Save extra data into session. # While Basic LTI 1.0 specifies that the message is to be signed using OAuth, implying # that any GET parameters should be stripped from the base URL and included as signed # parameters, typical LTI Tool Consumer implementations do not support this behaviour. As # a workaround, we accept TPA parameters from LTI custom parameters prefixed with "tpa_". for field_name in self.setting('FIELDS_STORED_IN_SESSION', []): if 'custom_tpa_' + field_name in validated_lti_params: self.strategy.session_set( field_name, validated_lti_params['custom_tpa_' + field_name]) if 'custom_tpa_' + REDIRECT_FIELD_NAME in validated_lti_params: # Check and sanitize a user-defined GET/POST next field value redirect_uri = validated_lti_params['custom_tpa_' + REDIRECT_FIELD_NAME] if self.setting('SANITIZE_REDIRECTS', True): redirect_uri = sanitize_redirect(self.strategy.request_host(), redirect_uri) self.strategy.session_set( REDIRECT_FIELD_NAME, redirect_uri or self.setting('LOGIN_REDIRECT_URL'))
def update_or_create_user_profile(backend, user, response, *args, **kwargs): li_access_token = response.get('access_token') li_resp = requests.get(USER_INFO_LI_REQUEST_URL.format(li_access_token)) li_resp_json = li_resp.json() li_email = li_resp_json.get('emailAddress') if li_email not in settings.VALID_EMAILS: raise AuthFailed(backend, 'This is not a whitelisted email') user_profile, created = UserProfile.objects.get_or_create(user=user) user_profile.li_email = li_email user_profile.li_first_name = li_resp_json.get('firstName') user_profile.li_last_name = li_resp_json.get('lastName') user_profile.li_picture_url = li_resp_json.get('pictureUrl') user_profile.li_profile_url = li_resp_json.get('publicProfileUrl') user_profile.save()
def auth_complete(self, *args, **kwargs): """Complete auth process""" response = self.consumer().complete( dict(self.data.items()), self.strategy.absolute_uri(self.redirect_uri)) if not response: raise AuthException(self, 'OpenID relying party endpoint') elif response.status == SUCCESS: kwargs.update({'response': response, 'backend': self}) return self.strategy.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 login process, must return user instance""" self.process_error(self.data) access_token = None key, secret = self.get_key_and_secret() try: shop_url = self.data.get('shop') self.shopifyAPI.Session.setup(api_key=key, secret=secret) shopify_session = self.shopifyAPI.Session(shop_url, self.data) access_token = shopify_session.token except self.shopifyAPI.ValidationException: raise AuthCanceled(self) else: if not access_token: raise AuthFailed(self, 'Authentication Failed') return self.do_auth(access_token, shop_url, shopify_session.url, *args, **kwargs)
def odnoklassniki_api(backend, 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(backend, msg.format(request_type)) return backend.get_json(api_url + 'fb.do', params=data)
def request(self, url, method='GET', *args, **kwargs): kwargs.setdefault('headers', {}) if self.setting('VERIFY_SSL') is not None: kwargs.setdefault('verify', self.setting('VERIFY_SSL')) kwargs.setdefault('timeout', self.setting('REQUESTS_TIMEOUT') or self.setting('URLOPEN_TIMEOUT')) if self.SEND_USER_AGENT and 'User-Agent' not in kwargs['headers']: kwargs['headers']['User-Agent'] = user_agent() try: if self.SSL_PROTOCOL: session = SSLHttpAdapter.ssl_adapter_session(self.SSL_PROTOCOL) response = session.request(method, url, *args, **kwargs) else: response = request(method, url, *args, **kwargs) except ConnectionError as err: raise AuthFailed(self, str(err)) response.raise_for_status() return response
def auth_complete(self, *args, **kwargs): if 'idtoken' not in self.data: raise AuthMissingParameter(self, 'idtoken') if 'access_token' not in self.data: raise AuthMissingParameter(self, 'access_token') try: idinfo = client.verify_id_token( self.data['idtoken'], settings.SOCIAL_AUTH_GOOGLE_SIGNIN_KEY) # If multiple clients access the backend server: if idinfo['aud'] != settings.SOCIAL_AUTH_GOOGLE_SIGNIN_KEY: raise crypt.AppIdentityError("Unrecognized client.") if idinfo['iss'] not in [ 'accounts.google.com', 'https://accounts.google.com' ]: raise crypt.AppIdentityError("Wrong issuer.") except crypt.AppIdentityError, e: raise AuthFailed(self, str(e))
def user_data(self, access_token, *args, **kwargs): """Loads user data from service""" user_data = super(GithubMemberOAuth2, self).user_data( access_token, *args, **kwargs ) does_not_belong = AuthFailed(self, 'User doesn\'t belong to ' 'the organization') try: res = self.request(self.member_url(user_data), params={ 'access_token': access_token }) if user_data.get('login') not in [user['login'] for user in res.json()]: raise does_not_belong except HTTPError as err: # if the user is a member of the organization, response code # will be 204, see http://bit.ly/ZS6vFl if err.response.status_code != 204: raise does_not_belong return user_data
def create_user(backend, details, response, uid, username, user=None, *args, **kwargs): """ Creates user. Depends on get_username pipeline. """ if user: return {'user': user} if not username: return None email = details.get('email') original_email = None # email is required if not email: message = _( """your social account needs to have a verified email address in order to proceed.""" ) raise AuthFailed(backend, message) # Avoid hitting field max length if email and len(email) > 75: original_email = email email = '' return { 'user': UserSocialAuth.create_user(username=username, email=email, sync_emailaddress=False), 'original_email': original_email, 'is_new': True }
def verify_auth_sig(self): correct_key = self.get_auth_sig() key = self.data['auth_sig'].lower() if correct_key != key: raise AuthFailed(self, 'Wrong authorization key')
class AuthFailedTest(BaseExceptionTestCase): exception = AuthFailed('foobar', 'wrong_user') expected_message = 'Authentication failed: wrong_user'
def process_error(self, data): if data.get('error'): error = self.data.get('error_description') or self.data['error'] raise AuthFailed(self, error)
class AuthFailedDeniedTest(BaseExceptionTestCase): exception = AuthFailed('foobar', 'access_denied') expected_message = 'Authentication process was canceled'
def auth_complete(self, *args, **kwargs): """Completes login process, must return user instance""" token = self.data.get('jwt', {}) if not token: raise AuthFailed(self, 'Authentication Failed') return self.do_auth(token, *args, **kwargs)
def _user_id(self, response): user_id = response.identity_url.rsplit('/', 1)[-1] if not user_id.isdigit(): raise AuthFailed(self, 'Missing Steam Id') return user_id