def test_already_associated_exception_populates_dashboard_with_error(self): # Instrument the pipeline with an exception. We test that the # exception is raised correctly separately, so it's ok that we're # raising it artificially here. This makes the linked=True artificial # in the final assert because in practice the account would be # unlinked, but getting that behavior is cumbersome here and already # covered in other tests. Using linked=True does, however, let us test # that the duplicate error has no effect on the state of the controls. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete') strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) user = self.create_user_models_for_existing_account( strategy, '*****@*****.**', 'password', self.get_username()) self.assert_social_auth_exists_for_user(user, strategy) self.client.get('/login') self.client.get(pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN)) actions.do_complete(request.backend, social_views._do_login) # pylint: disable=protected-access with self._patch_edxmako_current_request(strategy.request): student_views.signin_user(strategy.request) student_views.login_user(strategy.request) actions.do_complete(request.backend, social_views._do_login, user=user) # pylint: disable=protected-access # Monkey-patch storage for messaging; pylint: disable=protected-access request._messages = fallback.FallbackStorage(request) middleware.ExceptionMiddleware().process_exception( request, exceptions.AuthAlreadyAssociated(self.provider.backend_name, 'account is already in use.')) self.assert_account_settings_context_looks_correct( account_settings_context(request), user, duplicate=True, linked=True)
def test_full_pipeline_succeeds_for_unlinking_account(self): # First, create, the request and strategy that store pipeline state, # configure the backend, and mock out wire traffic. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete') strategy.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) user = self.create_user_models_for_existing_account( strategy, '*****@*****.**', 'password', self.get_username()) self.assert_social_auth_exists_for_user(user, strategy) # We're already logged in, so simulate that the cookie is set correctly self.set_logged_in_cookie(request) # Instrument the pipeline to get to the dashboard with the full # expected state. self.client.get( pipeline.get_login_url(self.PROVIDER_CLASS.NAME, pipeline.AUTH_ENTRY_LOGIN)) actions.do_complete(strategy, social_views._do_login) # pylint: disable-msg=protected-access mako_middleware_process_request(strategy.request) student_views.signin_user(strategy.request) student_views.login_user(strategy.request) actions.do_complete(strategy, social_views._do_login, user=user) # pylint: disable-msg=protected-access # First we expect that we're in the linked state, with a backend entry. self.assert_dashboard_response_looks_correct(student_views.dashboard(request), user, linked=True) self.assert_social_auth_exists_for_user(request.user, strategy) # Fire off the disconnect pipeline to unlink. self.assert_redirect_to_dashboard_looks_correct(actions.do_disconnect( request.social_strategy, request.user, None, redirect_field_name=auth.REDIRECT_FIELD_NAME)) # Now we expect to be in the unlinked state, with no backend entry. self.assert_dashboard_response_looks_correct(student_views.dashboard(request), user, linked=False) self.assert_social_auth_does_not_exist_for_user(user, strategy)
def mobile_persona_int(request, backend="persona", *args, **kwargs): assertion = request.POST["assertion"] errors = [] api_key = None user_id = 0 try: do_complete(request.social_strategy, _do_login, request.user, redirect_name="", *args, **kwargs) picup_profile = get_or_create_profile(request.user) api_key = picup_profile.api_key user_id = picup_profile.user.id except Exception as e: import traceback traceback.print_exc() errors.append(["auth_failed"]) response = requests.post("https://browserid.org/verify", data={"assertion": assertion, "audience": "picup.it"}) response_json = json.loads(response.text) response_json["errors"] = errors if api_key: response_json["api_key"] = api_key if user_id > 0: response_json["user_id"] = user_id response_json = json.dumps(response_json) my_response = MyResponse() my_response.text = response_json return my_response
def test_full_pipeline_succeeds_for_unlinking_account(self): # First, create, the request and strategy that store pipeline state, # configure the backend, and mock out wire traffic. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete') strategy.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) user = self.create_user_models_for_existing_account( strategy, '*****@*****.**', 'password', self.get_username()) self.assert_social_auth_exists_for_user(user, strategy) # Instrument the pipeline to get to the dashboard with the full # expected state. self.client.get( pipeline.get_login_url(self.PROVIDER_CLASS.NAME, pipeline.AUTH_ENTRY_LOGIN)) actions.do_complete(strategy, social_views._do_login) # pylint: disable-msg=protected-access mako_middleware_process_request(strategy.request) student_views.signin_user(strategy.request) student_views.login_user(strategy.request) actions.do_complete(strategy, social_views._do_login, user=user) # pylint: disable-msg=protected-access # First we expect that we're in the linked state, with a backend entry. self.assert_dashboard_response_looks_correct(student_views.dashboard(request), user, linked=True) self.assert_social_auth_exists_for_user(request.user, strategy) # Fire off the disconnect pipeline to unlink. self.assert_redirect_to_dashboard_looks_correct(actions.do_disconnect( request.social_strategy, request.user, None, redirect_field_name=auth.REDIRECT_FIELD_NAME)) # Now we expect to be in the unlinked state, with no backend entry. self.assert_dashboard_response_looks_correct(student_views.dashboard(request), user, linked=False) self.assert_social_auth_does_not_exist_for_user(user, strategy)
def test_already_associated_exception_populates_dashboard_with_error(self): # Instrument the pipeline with an exception. We test that the # exception is raised correctly separately, so it's ok that we're # raising it artificially here. This makes the linked=True artificial # in the final assert because in practice the account would be # unlinked, but getting that behavior is cumbersome here and already # covered in other tests. Using linked=True does, however, let us test # that the duplicate error has no effect on the state of the controls. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete') strategy.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) user = self.create_user_models_for_existing_account( strategy, '*****@*****.**', 'password', self.get_username()) self.assert_social_auth_exists_for_user(user, strategy) self.client.get('/login') self.client.get(pipeline.get_login_url(self.PROVIDER_CLASS.NAME, pipeline.AUTH_ENTRY_LOGIN)) actions.do_complete(strategy, social_views._do_login) # pylint: disable-msg=protected-access mako_middleware_process_request(strategy.request) student_views.signin_user(strategy.request) student_views.login_user(strategy.request) actions.do_complete(strategy, social_views._do_login, user=user) # pylint: disable-msg=protected-access # Monkey-patch storage for messaging; pylint: disable-msg=protected-access request._messages = fallback.FallbackStorage(request) middleware.ExceptionMiddleware().process_exception( request, exceptions.AuthAlreadyAssociated(self.PROVIDER_CLASS.BACKEND_CLASS.name, 'account is already in use.')) self.assert_dashboard_response_looks_correct( student_views.dashboard(request), user, duplicate=True, linked=True)
def test_linking_already_associated_account_raises_auth_already_associated( self): # This is of a piece with # test_already_associated_exception_populates_dashboard_with_error. It # verifies the exception gets raised when we expect; the latter test # covers exception handling. email = '*****@*****.**' password = '******' username = self.get_username() _, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete') backend = strategy.request.backend backend.auth_complete = mock.MagicMock( return_value=self.fake_auth_complete(strategy)) linked_user = self.create_user_models_for_existing_account( strategy, email, password, username) unlinked_user = social_utils.Storage.user.create_user( email='other_' + email, password=password, username='******' + username) self.assert_social_auth_exists_for_user(linked_user, strategy) self.assert_social_auth_does_not_exist_for_user( unlinked_user, strategy) with self.assertRaises(exceptions.AuthAlreadyAssociated): # pylint: disable=protected-access actions.do_complete(backend, social_views._do_login, user=unlinked_user)
def run_oauth(self, m, user=None): strategy = DjangoStrategy(DjangoStorage) backend = self.Backend_Class(strategy, redirect_uri=self.client_complete_url) start_url = do_auth(backend).url start_query = parse_qs(urlparse(start_url).query) # set 'state' in client backend.data.update({'state': start_query['state']}) m.get(backend.USER_DATA_URL, json={"username": self.social_username, "email": self.social_email}, status_code=200) m.post(backend.ACCESS_TOKEN_URL, json={'access_token': self.access_token, 'token_type': self.token_type, 'expires_in': self.expires_in, 'scope': self.scope, 'refresh_token': self.refresh_token}, status_code=200) def _login(backend, user, social_user): backend.strategy.session_set('username', user.username) do_complete(backend, user=user, login=_login) social = backend.strategy.storage.user.get_social_auth(backend.name, self.social_username) return strategy.session_get('username'), social, backend
def test_full_pipeline_succeeds_for_unlinking_account(self): # First, create, the request and strategy that store pipeline state, # configure the backend, and mock out wire traffic. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete') request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) user = self.create_user_models_for_existing_account( strategy, '*****@*****.**', 'password', self.get_username()) self.assert_social_auth_exists_for_user(user, strategy) # We're already logged in, so simulate that the cookie is set correctly self.set_logged_in_cookies(request) # Instrument the pipeline to get to the dashboard with the full # expected state. self.client.get( pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN)) actions.do_complete(request.backend, social_views._do_login) # pylint: disable=protected-access with self._patch_edxmako_current_request(strategy.request): student_views.signin_user(strategy.request) student_views.login_user(strategy.request) actions.do_complete(request.backend, social_views._do_login, user=user) # pylint: disable=protected-access # First we expect that we're in the linked state, with a backend entry. self.assert_account_settings_context_looks_correct(account_settings_context(request), user, linked=True) self.assert_social_auth_exists_for_user(request.user, strategy) # Fire off the disconnect pipeline to unlink. self.assert_redirect_to_dashboard_looks_correct(actions.do_disconnect( request.backend, request.user, None, redirect_field_name=auth.REDIRECT_FIELD_NAME)) # Now we expect to be in the unlinked state, with no backend entry. self.assert_account_settings_context_looks_correct(account_settings_context(request), user, linked=False) self.assert_social_auth_does_not_exist_for_user(user, strategy)
def test_full_pipeline_succeeds_registering_new_account(self): # First, create, the request and strategy that store pipeline state. # Mock out wire traffic. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_REGISTER, redirect_uri='social:complete') strategy.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) # Begin! Grab the registration page and check the login control on it. self.assert_register_response_before_pipeline_looks_correct(self.client.get('/register')) # The pipeline starts by a user GETting /auth/login/<provider>. # Synthesize that request and check that it redirects to the correct # provider page. self.assert_redirect_to_provider_looks_correct(self.client.get( pipeline.get_login_url(self.PROVIDER_CLASS.NAME, pipeline.AUTH_ENTRY_LOGIN))) # Next, the provider makes a request against /auth/complete/<provider>. # pylint:disable-msg=protected-access self.assert_redirect_to_register_looks_correct(actions.do_complete(strategy, social_views._do_login)) mako_middleware_process_request(strategy.request) # At this point we know the pipeline has resumed correctly. Next we # fire off the view that displays the registration form. self.assert_register_response_in_pipeline_looks_correct( student_views.register_user(strategy.request), pipeline.get(request)['kwargs']) # Next, we invoke the view that handles the POST. Not all providers # supply email. Manually add it as the user would have to; this # also serves as a test of overriding provider values. Always provide a # password for us to check that we override it properly. overridden_password = strategy.request.POST.get('password') email = '*****@*****.**' if not strategy.request.POST.get('email'): strategy.request.POST = self.get_registration_post_vars({'email': email}) # The user must not exist yet... with self.assertRaises(auth_models.User.DoesNotExist): self.get_user_by_email(strategy, email) # ...but when we invoke create_account the existing edX view will make # it, but not social auths. The pipeline creates those later. self.assert_json_success_response_looks_correct(student_views.create_account(strategy.request)) # We've overridden the user's password, so authenticate() with the old # value won't work: created_user = self.get_user_by_email(strategy, email) self.assert_password_overridden_by_pipeline(overridden_password, created_user.username) # At this point the user object exists, but there is no associated # social auth. self.assert_social_auth_does_not_exist_for_user(created_user, strategy) # Pick the pipeline back up. This will create the account association # and send the user to the dashboard, where the association will be # displayed. self.assert_redirect_to_dashboard_looks_correct( actions.do_complete(strategy, social_views._do_login, user=created_user)) self.assert_social_auth_exists_for_user(created_user, strategy) self.assert_dashboard_response_looks_correct(student_views.dashboard(request), created_user, linked=True)
def test_full_pipeline_succeeds_for_signing_in_to_existing_active_account(self): # First, create, the request and strategy that store pipeline state, # configure the backend, and mock out wire traffic. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri="social:complete" ) strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) pipeline.analytics.track = mock.MagicMock() user = self.create_user_models_for_existing_account( strategy, "*****@*****.**", "password", self.get_username() ) self.assert_social_auth_exists_for_user(user, strategy) self.assertTrue(user.is_active) # Begin! Ensure that the login form contains expected controls before # the user starts the pipeline. self.assert_login_response_before_pipeline_looks_correct(self.client.get("/login")) # The pipeline starts by a user GETting /auth/login/<provider>. # Synthesize that request and check that it redirects to the correct # provider page. self.assert_redirect_to_provider_looks_correct( self.client.get(pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN)) ) # Next, the provider makes a request against /auth/complete/<provider> # to resume the pipeline. # pylint: disable=protected-access self.assert_redirect_to_login_looks_correct(actions.do_complete(request.backend, social_views._do_login)) # At this point we know the pipeline has resumed correctly. Next we # fire off the view that displays the login form and posts it via JS. with self._patch_edxmako_current_request(strategy.request): self.assert_login_response_in_pipeline_looks_correct(student_views.signin_user(strategy.request)) # Next, we invoke the view that handles the POST, and expect it # redirects to /auth/complete. In the browser ajax handlers will # redirect the user to the dashboard; we invoke it manually here. self.assert_json_success_response_looks_correct(student_views.login_user(strategy.request)) # We should be redirected back to the complete page, setting # the "logged in" cookie for the marketing site. self.assert_logged_in_cookie_redirect( actions.do_complete( request.backend, social_views._do_login, request.user, None, # pylint: disable=protected-access redirect_field_name=auth.REDIRECT_FIELD_NAME, ) ) # Set the cookie and try again self.set_logged_in_cookies(request) self.assert_redirect_to_dashboard_looks_correct( actions.do_complete(request.backend, social_views._do_login, user=user) ) self.assert_account_settings_context_looks_correct(account_settings_context(request), user)
def test_full_pipeline_succeeds_registering_new_account(self): # First, create, the request and strategy that store pipeline state. # Mock out wire traffic. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_REGISTER, redirect_uri='social:complete') strategy.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) # Begin! Grab the registration page and check the login control on it. self.assert_register_response_before_pipeline_looks_correct(self.client.get('/register')) # The pipeline starts by a user GETting /auth/login/<provider>. # Synthesize that request and check that it redirects to the correct # provider page. self.assert_redirect_to_provider_looks_correct(self.client.get( pipeline.get_login_url(self.PROVIDER_CLASS.NAME, pipeline.AUTH_ENTRY_LOGIN))) # Next, the provider makes a request against /auth/complete/<provider>. # pylint:disable-msg=protected-access self.assert_redirect_to_register_looks_correct(actions.do_complete(strategy, social_views._do_login)) # At this point we know the pipeline has resumed correctly. Next we # fire off the view that displays the registration form. self.assert_register_response_in_pipeline_looks_correct( student_views.register_user(strategy.request), pipeline.get(request)['kwargs']) # Next, we invoke the view that handles the POST. Not all providers # supply email. Manually add it as the user would have to; this # also serves as a test of overriding provider values. Always provide a # password for us to check that we override it properly. overridden_password = strategy.request.POST.get('password') email = '*****@*****.**' if not strategy.request.POST.get('email'): strategy.request.POST = self.get_registration_post_vars({'email': email}) # The user must not exist yet... with self.assertRaises(auth_models.User.DoesNotExist): self.get_user_by_email(strategy, email) # ...but when we invoke create_account the existing edX view will make # it, but not social auths. The pipeline creates those later. self.assert_json_success_response_looks_correct(student_views.create_account(strategy.request)) # We've overridden the user's password, so authenticate() with the old # value won't work: created_user = self.get_user_by_email(strategy, email) self.assert_password_overridden_by_pipeline(overridden_password, created_user.username) # At this point the user object exists, but there is no associated # social auth. self.assert_social_auth_does_not_exist_for_user(created_user, strategy) # Pick the pipeline back up. This will create the account association # and send the user to the dashboard, where the association will be # displayed. self.assert_redirect_to_dashboard_looks_correct( actions.do_complete(strategy, social_views._do_login, user=created_user)) self.assert_social_auth_exists_for_user(created_user, strategy) self.assert_dashboard_response_looks_correct(student_views.dashboard(request), created_user, linked=True)
def test_full_pipeline_succeeds_for_signing_in_to_existing_active_account(self): # First, create, the request and strategy that store pipeline state, # configure the backend, and mock out wire traffic. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete') strategy.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) pipeline.analytics.track = mock.MagicMock() user = self.create_user_models_for_existing_account( strategy, '*****@*****.**', 'password', self.get_username()) self.assert_social_auth_exists_for_user(user, strategy) self.assertTrue(user.is_active) # Begin! Ensure that the login form contains expected controls before # the user starts the pipeline. self.assert_login_response_before_pipeline_looks_correct(self.client.get('/login')) # The pipeline starts by a user GETting /auth/login/<provider>. # Synthesize that request and check that it redirects to the correct # provider page. self.assert_redirect_to_provider_looks_correct(self.client.get( pipeline.get_login_url(self.PROVIDER_CLASS.NAME, pipeline.AUTH_ENTRY_LOGIN))) # Next, the provider makes a request against /auth/complete/<provider> # to resume the pipeline. # pylint: disable-msg=protected-access self.assert_redirect_to_login_looks_correct(actions.do_complete(strategy, social_views._do_login)) mako_middleware_process_request(strategy.request) # At this point we know the pipeline has resumed correctly. Next we # fire off the view that displays the login form and posts it via JS. self.assert_login_response_in_pipeline_looks_correct(student_views.signin_user(strategy.request)) # Next, we invoke the view that handles the POST, and expect it # redirects to /auth/complete. In the browser ajax handlers will # redirect the user to the dashboard; we invoke it manually here. self.assert_json_success_response_looks_correct(student_views.login_user(strategy.request)) # We should be redirected back to the complete page, setting # the "logged in" cookie for the marketing site. self.assert_logged_in_cookie_redirect(actions.do_complete( request.social_strategy, social_views._do_login, request.user, None, # pylint: disable-msg=protected-access redirect_field_name=auth.REDIRECT_FIELD_NAME )) # Set the cookie and try again self.set_logged_in_cookie(request) self.assert_redirect_to_dashboard_looks_correct( actions.do_complete(strategy, social_views._do_login, user=user)) self.assert_dashboard_response_looks_correct(student_views.dashboard(request), user)
def complete(request, backend, *args, **kwargs): return do_complete(request.strategy, _do_login, request.user, redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs)
def username_login(request, backend, *args, **kwargs): ''' login form processing''' if request.user.is_authenticated(): return redirect('user/dashboard') if request.method == 'POST': form = LoginForm(request.POST) users = User.objects.filter(username=request.POST['username']).count() if(users == 0): form.errors['__all__'] = 'There is no user with username: '******'username'] elif form.is_valid(): try: return do_complete(request.social_strategy, lambda strategy, user, social_user=None: auth_login(strategy.request, user), request.user) except exceptions.AuthException: form.errors['__all__'] = 'you have entered wrong username/password' else: form = LoginForm() # An unbound form return render(request, 'login.html', {'form' : form})
def complete_social_auth(request, backend, *args, **kwargs): return do_complete(request.backend, login_func, request.user, redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs)
def _complete(self, backend, *args, **kwargs): return do_complete( self.backend, login=lambda backend, user, social_user: self.login_user(user), user=self.get_current_user(), *args, **kwargs)
def do_login(self, after_complete_checks=True, user_data_body=None, expected_username=None): self.strategy.set_settings({ 'SOCIAL_AUTH_GITHUB_KEY': 'a-key', 'SOCIAL_AUTH_GITHUB_SECRET': 'a-secret-key', 'SOCIAL_AUTH_LOGIN_REDIRECT_URL': self.login_redirect_url, 'SOCIAL_AUTH_AUTHENTICATION_BACKENDS': ('social.backends.github.GithubOAuth2', ) }) start_url = do_auth(self.backend).url target_url = self.strategy.build_absolute_uri( '/complete/github/?code=foobar') start_query = parse_qs(urlparse(start_url).query) location_url = target_url + ('?' in target_url and '&' or '?') + \ 'state=' + start_query['state'] location_query = parse_qs(urlparse(location_url).query) HTTPretty.register_uri(HTTPretty.GET, start_url, status=301, location=location_url) HTTPretty.register_uri(HTTPretty.GET, location_url, status=200, body='foobar') response = requests.get(start_url) expect(response.url).to.equal(location_url) expect(response.text).to.equal('foobar') HTTPretty.register_uri(HTTPretty.POST, uri=self.backend.ACCESS_TOKEN_URL, status=200, body=self.access_token_body or '', content_type='text/json') if self.user_data_url: user_data_body = user_data_body or self.user_data_body or '' HTTPretty.register_uri(HTTPretty.GET, self.user_data_url, body=user_data_body, content_type='text/json') self.strategy.set_request_data(location_query, self.backend) def _login(backend, user, social_user): backend.strategy.session_set('username', user.username) redirect = do_complete(self.backend, user=self.user, login=_login) if after_complete_checks: expect(self.strategy.session_get('username')).to.equal( expected_username or self.expected_username) expect(redirect.url).to.equal(self.login_redirect_url) return redirect
def do_login(self, after_complete_checks=True, user_data_body=None, expected_username=None): self.strategy.set_settings({ 'SOCIAL_AUTH_GITHUB_KEY': 'a-key', 'SOCIAL_AUTH_GITHUB_SECRET': 'a-secret-key', 'SOCIAL_AUTH_LOGIN_REDIRECT_URL': self.login_redirect_url, 'SOCIAL_AUTH_AUTHENTICATION_BACKENDS': ( 'social.backends.github.GithubOAuth2', ) }) start_url = do_auth(self.strategy).url target_url = self.strategy.build_absolute_uri( '/complete/github/?code=foobar' ) start_query = parse_qs(urlparse(start_url).query) location_url = target_url + ('?' in target_url and '&' or '?') + \ 'state=' + start_query['state'] location_query = parse_qs(urlparse(location_url).query) HTTPretty.register_uri(HTTPretty.GET, start_url, status=301, location=location_url) HTTPretty.register_uri(HTTPretty.GET, location_url, status=200, body='foobar') response = requests.get(start_url) expect(response.url).to.equal(location_url) expect(response.text).to.equal('foobar') HTTPretty.register_uri(HTTPretty.GET, uri=self.backend.ACCESS_TOKEN_URL, status=200, body=self.access_token_body or '', content_type='text/json') if self.user_data_url: user_data_body = user_data_body or self.user_data_body or '' HTTPretty.register_uri(HTTPretty.GET, self.user_data_url, body=user_data_body, content_type='text/json') self.strategy.set_request_data(location_query) class Request(object):session = {} self.strategy.request = Request() def _login_lambda(strategy, user, social_user): strategy.request = Request() return strategy.session_set('username', user.username) redirect = do_complete( self.strategy, user=self.user, login=_login_lambda ) if after_complete_checks: expect(self.strategy.session_get('username')).to.equal( expected_username or self.expected_username ) expect(redirect.url).to.equal(self.login_redirect_url) return redirect
def complete(request, backend, *args, **kwargs): """Authentication complete view""" return do_complete(request.backend, _do_login, request.user, redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs)
def complete(backend, *args, **kwargs): """Authentication complete view, override this view if transaction management doesn't suit your needs.""" return do_complete(g.strategy, login=do_login, user=g.user, *args, **kwargs)
def complete(request, *args, **kwargs): do_login = module_member(request.backend.setting('LOGIN_FUNCTION')) return do_complete(request.backend, do_login, request.user, redirect_name='next', *args, **kwargs)
def complete(request, backend, *args, **kwargs): """Authentication complete view, override this view if transaction management doesn't suit your needs.""" return do_complete(request.strategy, _do_login, request.user, redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs)
def complete(request, backend, *args, **kwargs): backend = get_backend(BACKENDS, backend, request.strategy) if backend: return do_complete(backend, _do_login, request.user, redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs) raise Http404
def test_linking_already_associated_account_raises_auth_already_associated(self): # This is of a piece with # test_already_associated_exception_populates_dashboard_with_error. It # verifies the exception gets raised when we expect; the latter test # covers exception handling. email = '*****@*****.**' password = '******' username = self.get_username() _, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete') strategy.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) linked_user = self.create_user_models_for_existing_account(strategy, email, password, username) unlinked_user = social_utils.Storage.user.create_user( email='other_' + email, password=password, username='******' + username) self.assert_social_auth_exists_for_user(linked_user, strategy) self.assert_social_auth_does_not_exist_for_user(unlinked_user, strategy) with self.assertRaises(exceptions.AuthAlreadyAssociated): actions.do_complete(strategy, social_views._do_login, user=unlinked_user) # pylint: disable-msg=protected-access
def complete(request, backend, *args, **kwargs): """Authentication complete view""" # if request.is_base: # # stored state available # stored = request.backend.strategy.session_get('next') # return HttpResponseRedirect(stored + request.build_absolute_uri()[6:].lstrip('/').split('/', 1)[1]) return do_complete(request.backend, _do_login, request.user, redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs)
def test_new_account_registration_fails_if_email_exists(self): request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_REGISTER, redirect_uri='social:complete') strategy.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) # pylint:disable-msg=protected-access self.assert_redirect_to_register_looks_correct(actions.do_complete(strategy, social_views._do_login)) self.assert_register_response_in_pipeline_looks_correct( student_views.register_user(strategy.request), pipeline.get(request)['kwargs']) strategy.request.POST = self.get_registration_post_vars() # Create twice: once successfully, and once causing a collision. student_views.create_account(strategy.request) self.assert_json_failure_response_is_username_collision(student_views.create_account(strategy.request))
def test_full_pipeline_succeeds_for_linking_account(self): # First, create, the request and strategy that store pipeline state, # configure the backend, and mock out wire traffic. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete') request.backend.auth_complete = mock.MagicMock( return_value=self.fake_auth_complete(strategy)) pipeline.analytics.track = mock.MagicMock() request.user = self.create_user_models_for_existing_account( strategy, '*****@*****.**', 'password', self.get_username(), skip_social_auth=True) # Instrument the pipeline to get to the dashboard with the full # expected state. self.client.get( pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN)) actions.do_complete(request.backend, social_views._do_login) # pylint: disable=protected-access mako_middleware_process_request(strategy.request) student_views.signin_user(strategy.request) student_views.login_user(strategy.request) actions.do_complete(request.backend, social_views._do_login) # pylint: disable=protected-access # First we expect that we're in the unlinked state, and that there # really is no association in the backend. self.assert_account_settings_context_looks_correct( account_settings_context(request), request.user, linked=False) self.assert_social_auth_does_not_exist_for_user(request.user, strategy) # We should be redirected back to the complete page, setting # the "logged in" cookie for the marketing site. self.assert_logged_in_cookie_redirect( actions.do_complete( request.backend, social_views._do_login, request.user, None, # pylint: disable=protected-access redirect_field_name=auth.REDIRECT_FIELD_NAME)) # Set the cookie and try again self.set_logged_in_cookies(request) # Fire off the auth pipeline to link. self.assert_redirect_to_dashboard_looks_correct( actions.do_complete( request.backend, social_views._do_login, request.user, None, # pylint: disable=protected-access redirect_field_name=auth.REDIRECT_FIELD_NAME)) # Now we expect to be in the linked state, with a backend entry. self.assert_social_auth_exists_for_user(request.user, strategy) self.assert_account_settings_context_looks_correct( account_settings_context(request), request.user, linked=True)
def test_new_account_registration_assigns_distinct_username_on_collision(self): original_username = self.get_username() request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_REGISTER, redirect_uri='social:complete') # Create a colliding username in the backend, then proceed with # assignment via pipeline to make sure a distinct username is created. strategy.storage.user.create_user(username=self.get_username(), email='*****@*****.**', password='******') strategy.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) # pylint: disable-msg=protected-access self.assert_redirect_to_register_looks_correct(actions.do_complete(strategy, social_views._do_login)) distinct_username = pipeline.get(request)['kwargs']['username'] self.assertNotEqual(original_username, distinct_username)
def run_oauth(self, m, user=None): strategy = DjangoStrategy(DjangoStorage) backend = self.Backend_Class(strategy, redirect_uri=self.client_complete_url) start_url = do_auth(backend).url start_query = parse_qs(urlparse(start_url).query) # set 'state' in client backend.data.update({'state': start_query['state']}) m.get(backend.USER_DATA_URL, json={ "username": self.social_username, "email": self.social_email }, status_code=200) m.post(backend.ACCESS_TOKEN_URL, json={ 'access_token': self.access_token, 'token_type': self.token_type, 'expires_in': self.expires_in, 'scope': self.scope, 'refresh_token': self.refresh_token }, status_code=200) def _login(backend, user, social_user): backend.strategy.session_set('username', user.username) do_complete(backend, user=user, login=_login) social = backend.strategy.storage.user.get_social_auth( backend.name, self.social_username) return strategy.session_get('username'), social, backend
def mobile_persona_int(request, backend='persona', *args, **kwargs): assertion = request.POST['assertion'] errors = [] api_key = None user_id = 0 try: do_complete(request.social_strategy, _do_login, request.user, redirect_name='', *args, **kwargs) picup_profile = get_or_create_profile(request.user) api_key = picup_profile.api_key user_id = picup_profile.user.id except Exception as e: import traceback traceback.print_exc() errors.append(['auth_failed']) response = requests.post('https://browserid.org/verify', data={ 'assertion': assertion, 'audience': 'picup.it' }) response_json = json.loads(response.text) response_json['errors'] = errors if api_key: response_json['api_key'] = api_key if user_id > 0: response_json['user_id'] = user_id response_json = json.dumps(response_json) my_response = MyResponse() my_response.text = response_json return my_response
def test_full_pipeline_succeeds_for_signing_in_to_existing_active_account(self): # First, create, the request and strategy that store pipeline state, # configure the backend, and mock out wire traffic. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete') strategy.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) user = self.create_user_models_for_existing_account( strategy, '*****@*****.**', 'password', self.get_username()) self.assert_social_auth_exists_for_user(user, strategy) self.assertTrue(user.is_active) # Begin! Ensure that the login form contains expected controls before # the user starts the pipeline. self.assert_login_response_before_pipeline_looks_correct(self.client.get('/login')) # The pipeline starts by a user GETting /auth/login/<provider>. # Synthesize that request and check that it redirects to the correct # provider page. self.assert_redirect_to_provider_looks_correct(self.client.get( pipeline.get_login_url(self.PROVIDER_CLASS.NAME, pipeline.AUTH_ENTRY_LOGIN))) # Next, the provider makes a request against /auth/complete/<provider> # to resume the pipeline. # pylint: disable-msg=protected-access self.assert_redirect_to_login_looks_correct(actions.do_complete(strategy, social_views._do_login)) mako_middleware_process_request(strategy.request) # At this point we know the pipeline has resumed correctly. Next we # fire off the view that displays the login form and posts it via JS. self.assert_login_response_in_pipeline_looks_correct(student_views.signin_user(strategy.request)) # Next, we invoke the view that handles the POST, and expect it # redirects to /auth/complete. In the browser ajax handlers will # redirect the user to the dashboard; we invoke it manually here. self.assert_json_success_response_looks_correct(student_views.login_user(strategy.request)) self.assert_redirect_to_dashboard_looks_correct( actions.do_complete(strategy, social_views._do_login, user=user)) self.assert_dashboard_response_looks_correct(student_views.dashboard(request), user)
def test_full_pipeline_succeeds_for_linking_account(self): # First, create, the request and strategy that store pipeline state, # configure the backend, and mock out wire traffic. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri="social:complete" ) request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) pipeline.analytics.track = mock.MagicMock() request.user = self.create_user_models_for_existing_account( strategy, "*****@*****.**", "password", self.get_username(), skip_social_auth=True ) # Instrument the pipeline to get to the dashboard with the full # expected state. self.client.get(pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN)) actions.do_complete(request.backend, social_views._do_login) # pylint: disable=protected-access student_views.signin_user(strategy.request) student_views.login_user(strategy.request) actions.do_complete(request.backend, social_views._do_login) # pylint: disable=protected-access # First we expect that we're in the unlinked state, and that there # really is no association in the backend. self.assert_account_settings_context_looks_correct( account_settings_context(request), request.user, linked=False ) self.assert_social_auth_does_not_exist_for_user(request.user, strategy) # We should be redirected back to the complete page, setting # the "logged in" cookie for the marketing site. self.assert_logged_in_cookie_redirect( actions.do_complete( request.backend, social_views._do_login, request.user, None, # pylint: disable=protected-access redirect_field_name=auth.REDIRECT_FIELD_NAME, ) ) # Set the cookie and try again self.set_logged_in_cookies(request) # Fire off the auth pipeline to link. self.assert_redirect_to_dashboard_looks_correct( actions.do_complete( request.backend, social_views._do_login, request.user, None, # pylint: disable=protected-access redirect_field_name=auth.REDIRECT_FIELD_NAME, ) ) # Now we expect to be in the linked state, with a backend entry. self.assert_social_auth_exists_for_user(request.user, strategy) self.assert_account_settings_context_looks_correct(account_settings_context(request), request.user, linked=True)
def do_login(self, after_complete_checks=True, user_data_body=None, expected_username=None): self.strategy.set_settings( { "SOCIAL_AUTH_GITHUB_KEY": "a-key", "SOCIAL_AUTH_GITHUB_SECRET": "a-secret-key", "SOCIAL_AUTH_LOGIN_REDIRECT_URL": self.login_redirect_url, "SOCIAL_AUTH_AUTHENTICATION_BACKENDS": ("social.backends.github.GithubOAuth2",), } ) start_url = do_auth(self.backend).url target_url = self.strategy.build_absolute_uri("/complete/github/?code=foobar") start_query = parse_qs(urlparse(start_url).query) location_url = target_url + ("?" in target_url and "&" or "?") + "state=" + start_query["state"] location_query = parse_qs(urlparse(location_url).query) HTTPretty.register_uri(HTTPretty.GET, start_url, status=301, location=location_url) HTTPretty.register_uri(HTTPretty.GET, location_url, status=200, body="foobar") response = requests.get(start_url) expect(response.url).to.equal(location_url) expect(response.text).to.equal("foobar") HTTPretty.register_uri( HTTPretty.POST, uri=self.backend.ACCESS_TOKEN_URL, status=200, body=self.access_token_body or "", content_type="text/json", ) if self.user_data_url: user_data_body = user_data_body or self.user_data_body or "" HTTPretty.register_uri(HTTPretty.GET, self.user_data_url, body=user_data_body, content_type="text/json") self.strategy.set_request_data(location_query, self.backend) def _login(backend, user, social_user): backend.strategy.session_set("username", user.username) redirect = do_complete(self.backend, user=self.user, login=_login) if after_complete_checks: expect(self.strategy.session_get("username")).to.equal(expected_username or self.expected_username) expect(redirect.url).to.equal(self.login_redirect_url) return redirect
def complete(request, backend, *args, **kwargs): """Authentication complete view, override this view if transaction management doesn't suit your needs.""" next_blob = request.session.pop('next_blob', None) error = request.GET.get('error') if error: return oauth_error(request) resp = do_complete(request.social_strategy, _do_login, request.user, redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs) if next_blob: alt_resp = _url_redirect_when_logged_in(request, next_blob) if alt_resp: return alt_resp return resp
def complete(request, backend, *args, **kwargs): """Authentication complete view, override this view if transaction management doesn't suit your needs.""" next_blob = request.session.pop("next_blob", None) error = request.GET.get("error") if error: return oauth_error(request) resp = do_complete( request.social_strategy, _do_login, request.user, redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs ) if next_blob: alt_resp = _url_redirect_when_logged_in(request, next_blob) if alt_resp: return alt_resp return resp
def signup(request, backend, *args, **kwargs): ''' registeration form ''' if request.user.is_authenticated(): return redirect('user/dashboard') if request.method == 'POST': form = RegisterationForm(request.POST) homo_emails = User.objects.filter(email=request.POST['email']).count() homo_usernames = User.objects.filter(username = request.POST['username']).count() if(homo_emails > 0): form.errors['email'] = 'this email id is already taken did you <a href="/forgot-password/">forgot</a> password' elif(homo_usernames > 0): form.errors['username'] = '******' elif form.is_valid(): try: return do_complete(request.social_strategy, lambda strategy, user, social_user=None: auth_login(strategy.request, user), request.user) except exceptions.AuthException: form.errors['__all__'] = 'you have entered wrong username/password' else : print 'got error !!!' print form.errors.keys() else: form = RegisterationForm() # An unbound form return render(request, 'register.html', { 'form': form, })
def complete(request, *args, **kwargs): do_login = module_member(request.strategy.setting('LOGIN_FUNCTION')) return do_complete(request.strategy, do_login, request.user, redirect_name='next', *args, **kwargs)
def complete(self, backend, *args, **kwargs): login = cherrypy.config.get(setting_name('LOGIN_METHOD')) do_login = module_member(login) if login else self.do_login user = getattr(cherrypy.request, 'user', None) return do_complete(self.strategy, do_login, user=user, *args, **kwargs)
def complete(request, backend, *args, **kwargs): """Authentication complete view, override this view if transaction management doesn't suit your needs.""" return do_complete(request.social_strategy, _do_login, request.user, redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs)
def do_login_with_partial_pipeline(self, before_complete=None): self.strategy.set_settings({ 'SOCIAL_AUTH_GITHUB_KEY': 'a-key', 'SOCIAL_AUTH_GITHUB_SECRET': 'a-secret-key', 'SOCIAL_AUTH_LOGIN_REDIRECT_URL': self.login_redirect_url, 'SOCIAL_AUTH_AUTHENTICATION_BACKENDS': ( 'social.backends.github.GithubOAuth2', ), 'SOCIAL_AUTH_PIPELINE': ( 'social.pipeline.social_auth.social_details', 'social.pipeline.social_auth.social_uid', 'social.pipeline.social_auth.auth_allowed', 'social.pipeline.partial.save_status_to_session', 'social.tests.pipeline.ask_for_password', 'social.pipeline.social_auth.social_user', 'social.pipeline.user.get_username', 'social.pipeline.user.create_user', 'social.pipeline.social_auth.associate_user', 'social.pipeline.social_auth.load_extra_data', 'social.tests.pipeline.set_password', 'social.pipeline.user.user_details' ) }) start_url = do_auth(self.strategy).url target_url = self.strategy.build_absolute_uri( '/complete/github/?code=foobar' ) start_query = parse_qs(urlparse(start_url).query) location_url = target_url + ('?' in target_url and '&' or '?') + \ 'state=' + start_query['state'] location_query = parse_qs(urlparse(location_url).query) HTTPretty.register_uri(HTTPretty.GET, start_url, status=301, location=location_url) HTTPretty.register_uri(HTTPretty.GET, location_url, status=200, body='foobar') response = requests.get(start_url) expect(response.url).to.equal(location_url) expect(response.text).to.equal('foobar') HTTPretty.register_uri(HTTPretty.GET, uri=self.backend.ACCESS_TOKEN_URL, status=200, body=self.access_token_body or '', content_type='text/json') if self.user_data_url: HTTPretty.register_uri(HTTPretty.GET, self.user_data_url, body=self.user_data_body or '', content_type='text/json') self.strategy.set_request_data(location_query) def _login(strategy, user, social_user): strategy.session_set('username', user.username) redirect = do_complete(self.strategy, user=self.user, login=_login) url = self.strategy.build_absolute_uri('/password') expect(redirect.url).to.equal(url) HTTPretty.register_uri(HTTPretty.GET, redirect.url, status=200, body='foobar') HTTPretty.register_uri(HTTPretty.POST, redirect.url, status=200) password = '******' requests.get(url) requests.post(url, data={'password': password}) data = parse_qs(HTTPretty.last_request.body) expect(data['password']).to.equal(password) self.strategy.session_set('password', data['password']) if before_complete: before_complete() redirect = do_complete(self.strategy, user=self.user, login=_login) expect(self.strategy.session_get('username')).to.equal( self.expected_username ) expect(redirect.url).to.equal(self.login_redirect_url)
def complete(backend, *args, **kwargs): """Authentication complete view, override this view if transaction management doesn't suit your needs.""" return do_complete(g.backend, login=do_login, user=g.user, *args, **kwargs)
def _complete(self, backend): do_complete( self.backend, login=lambda backend, user, social_user: self.login_user(user), user=self.get_current_user() )
def get_username(backend, redirect_uri): g.strategy = load_strategy() g.backend = load_backend(g.strategy, backend, redirect_uri=redirect_uri) do_complete(g.backend, login=do_login) return g.user.username
def _complete(self, backend): do_complete(self.strategy, login=lambda strategy, user: self.login_user(user), user=self.get_current_user())
def do_login_with_partial_pipeline(self, before_complete=None): self.strategy.set_settings({ 'SOCIAL_AUTH_GITHUB_KEY': 'a-key', 'SOCIAL_AUTH_GITHUB_SECRET': 'a-secret-key', 'SOCIAL_AUTH_LOGIN_REDIRECT_URL': self.login_redirect_url, 'SOCIAL_AUTH_AUTHENTICATION_BACKENDS': ('social.backends.github.GithubOAuth2', ), 'SOCIAL_AUTH_PIPELINE': ('social.pipeline.social_auth.social_details', 'social.pipeline.social_auth.social_uid', 'social.pipeline.social_auth.auth_allowed', 'social.pipeline.partial.save_status_to_session', 'social.tests.pipeline.ask_for_password', 'social.pipeline.social_auth.social_user', 'social.pipeline.user.get_username', 'social.pipeline.user.create_user', 'social.pipeline.social_auth.associate_user', 'social.pipeline.social_auth.load_extra_data', 'social.tests.pipeline.set_password', 'social.pipeline.user.user_details') }) start_url = do_auth(self.strategy).url target_url = self.strategy.build_absolute_uri( '/complete/github/?code=foobar') start_query = parse_qs(urlparse(start_url).query) location_url = target_url + ('?' in target_url and '&' or '?') + \ 'state=' + start_query['state'] location_query = parse_qs(urlparse(location_url).query) HTTPretty.register_uri(HTTPretty.GET, start_url, status=301, location=location_url) HTTPretty.register_uri(HTTPretty.GET, location_url, status=200, body='foobar') response = requests.get(start_url) expect(response.url).to.equal(location_url) expect(response.text).to.equal('foobar') HTTPretty.register_uri(HTTPretty.GET, uri=self.backend.ACCESS_TOKEN_URL, status=200, body=self.access_token_body or '', content_type='text/json') if self.user_data_url: HTTPretty.register_uri(HTTPretty.GET, self.user_data_url, body=self.user_data_body or '', content_type='text/json') self.strategy.set_request_data(location_query) def _login(strategy, user, social_user): strategy.session_set('username', user.username) redirect = do_complete(self.strategy, user=self.user, login=_login) url = self.strategy.build_absolute_uri('/password') expect(redirect.url).to.equal(url) HTTPretty.register_uri(HTTPretty.GET, redirect.url, status=200, body='foobar') HTTPretty.register_uri(HTTPretty.POST, redirect.url, status=200) password = '******' requests.get(url) requests.post(url, data={'password': password}) data = parse_qs(HTTPretty.last_request.body) expect(data['password']).to.equal(password) self.strategy.session_set('password', data['password']) if before_complete: before_complete() redirect = do_complete(self.strategy, user=self.user, login=_login) expect(self.strategy.session_get('username')).to.equal( self.expected_username) expect(redirect.url).to.equal(self.login_redirect_url)
def _complete(self, backend, *args, **kwargs): return do_complete(self.strategy, login=lambda strat, user: self.login_user(user), user=self.get_current_user(), *args, **kwargs)
def test_full_pipeline_succeeds_registering_new_account(self): # First, create, the request and strategy that store pipeline state. # Mock out wire traffic. request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_REGISTER, redirect_uri="social:complete" ) strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy)) # Begin! Grab the registration page and check the login control on it. self.assert_register_response_before_pipeline_looks_correct(self.client.get("/register")) # The pipeline starts by a user GETting /auth/login/<provider>. # Synthesize that request and check that it redirects to the correct # provider page. self.assert_redirect_to_provider_looks_correct( self.client.get(pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN)) ) # Next, the provider makes a request against /auth/complete/<provider>. # pylint: disable=protected-access self.assert_redirect_to_register_looks_correct(actions.do_complete(request.backend, social_views._do_login)) # At this point we know the pipeline has resumed correctly. Next we # fire off the view that displays the registration form. with self._patch_edxmako_current_request(request): self.assert_register_response_in_pipeline_looks_correct( student_views.register_user(strategy.request), pipeline.get(request)["kwargs"] ) # Next, we invoke the view that handles the POST. Not all providers # supply email. Manually add it as the user would have to; this # also serves as a test of overriding provider values. Always provide a # password for us to check that we override it properly. overridden_password = strategy.request.POST.get("password") email = "*****@*****.**" if not strategy.request.POST.get("email"): strategy.request.POST = self.get_registration_post_vars({"email": email}) # The user must not exist yet... with self.assertRaises(auth_models.User.DoesNotExist): self.get_user_by_email(strategy, email) # ...but when we invoke create_account the existing edX view will make # it, but not social auths. The pipeline creates those later. with self._patch_edxmako_current_request(strategy.request): self.assert_json_success_response_looks_correct(student_views.create_account(strategy.request)) # We've overridden the user's password, so authenticate() with the old # value won't work: created_user = self.get_user_by_email(strategy, email) self.assert_password_overridden_by_pipeline(overridden_password, created_user.username) # At this point the user object exists, but there is no associated # social auth. self.assert_social_auth_does_not_exist_for_user(created_user, strategy) # We should be redirected back to the complete page, setting # the "logged in" cookie for the marketing site. self.assert_logged_in_cookie_redirect( actions.do_complete( request.backend, social_views._do_login, request.user, None, # pylint: disable=protected-access redirect_field_name=auth.REDIRECT_FIELD_NAME, ) ) # Set the cookie and try again self.set_logged_in_cookies(request) self.assert_redirect_to_dashboard_looks_correct( actions.do_complete(strategy.request.backend, social_views._do_login, user=created_user) ) # Now the user has been redirected to the dashboard. Their third party account should now be linked. self.assert_social_auth_exists_for_user(created_user, strategy) self.assert_account_settings_context_looks_correct(account_settings_context(request), created_user, linked=True)
def complete(backend, *args, **kwargs): """Authentication complete view, override this view if transaction management doesn't suit your needs.""" return do_complete(g.strategy, login=lambda strat, user: login_user(user), user=g.user, *args, **kwargs)
def _complete(self, backend, *args, **kwargs): return do_complete( self.backend, login=lambda backend, user, social_user: self.login_user(user), user=self.get_current_user(), *args, **kwargs )
def do_login_with_partial_pipeline(self, before_complete=None): self.strategy.set_settings( { "SOCIAL_AUTH_GITHUB_KEY": "a-key", "SOCIAL_AUTH_GITHUB_SECRET": "a-secret-key", "SOCIAL_AUTH_LOGIN_REDIRECT_URL": self.login_redirect_url, "SOCIAL_AUTH_AUTHENTICATION_BACKENDS": ("social.backends.github.GithubOAuth2",), "SOCIAL_AUTH_PIPELINE": ( "social.pipeline.social_auth.social_details", "social.pipeline.social_auth.social_uid", "social.pipeline.social_auth.auth_allowed", "social.pipeline.partial.save_status_to_session", "social.tests.pipeline.ask_for_password", "social.pipeline.social_auth.social_user", "social.pipeline.user.get_username", "social.pipeline.user.create_user", "social.pipeline.social_auth.associate_user", "social.pipeline.social_auth.load_extra_data", "social.tests.pipeline.set_password", "social.pipeline.user.user_details", ), } ) start_url = do_auth(self.backend).url target_url = self.strategy.build_absolute_uri("/complete/github/?code=foobar") start_query = parse_qs(urlparse(start_url).query) location_url = target_url + ("?" in target_url and "&" or "?") + "state=" + start_query["state"] location_query = parse_qs(urlparse(location_url).query) HTTPretty.register_uri(HTTPretty.GET, start_url, status=301, location=location_url) HTTPretty.register_uri(HTTPretty.GET, location_url, status=200, body="foobar") response = requests.get(start_url) expect(response.url).to.equal(location_url) expect(response.text).to.equal("foobar") HTTPretty.register_uri( HTTPretty.GET, uri=self.backend.ACCESS_TOKEN_URL, status=200, body=self.access_token_body or "", content_type="text/json", ) if self.user_data_url: HTTPretty.register_uri( HTTPretty.GET, self.user_data_url, body=self.user_data_body or "", content_type="text/json" ) self.strategy.set_request_data(location_query, self.backend) def _login(backend, user, social_user): backend.strategy.session_set("username", user.username) redirect = do_complete(self.backend, user=self.user, login=_login) url = self.strategy.build_absolute_uri("/password") expect(redirect.url).to.equal(url) HTTPretty.register_uri(HTTPretty.GET, redirect.url, status=200, body="foobar") HTTPretty.register_uri(HTTPretty.POST, redirect.url, status=200) password = "******" requests.get(url) requests.post(url, data={"password": password}) data = parse_qs(HTTPretty.last_request.body) expect(data["password"]).to.equal(password) self.strategy.session_set("password", data["password"]) if before_complete: before_complete() redirect = do_complete(self.backend, user=self.user, login=_login) expect(self.strategy.session_get("username")).to.equal(self.expected_username) expect(redirect.url).to.equal(self.login_redirect_url)