auth: Redirect deactivated users with error for social auth backend.

Fixes #11937.

Also extracts the error message for a deactivated account to
`DEACTIVATED_ACCOUNT_ERROR`.
This commit is contained in:
Shubham Padia
2019-04-12 12:24:58 +08:00
committed by Tim Abbott
parent f71d8a7ed5
commit 3c09f226a4
5 changed files with 38 additions and 11 deletions

View File

@@ -116,6 +116,12 @@
</div>
{% endif %}
{% if is_deactivated %}
<div class="alert">
{{ deactivated_account_error }}
</div>
{% endif %}
{% if subdomain %}
<div class="alert">
{{ wrong_subdomain_error }}

View File

@@ -43,6 +43,8 @@ MIT_VALIDATION_ERROR = u'That user does not exist at MIT or is a ' + \
WRONG_SUBDOMAIN_ERROR = "Your Zulip account is not a member of the " + \
"organization associated with this subdomain. " + \
"Please contact %s with any questions!" % (FromAddress.SUPPORT,)
DEACTIVATED_ACCOUNT_ERROR = u"Your account is no longer active. " + \
u"Please contact your organization administrator to reactivate it."
def email_is_not_mit_mailing_list(email: str) -> None:
"""Prevent MIT mailing lists from signing up for Zulip"""
@@ -289,10 +291,7 @@ class OurAuthenticationForm(AuthenticationForm):
# We exclude mirror dummy accounts here. They should be treated as the
# user never having had an account, so we let them fall through to the
# normal invalid_login case below.
error_msg = (
u"Your account is no longer active. "
u"Please contact your organization administrator to reactivate it.")
raise ValidationError(mark_safe(error_msg))
raise ValidationError(mark_safe(DEACTIVATED_ACCOUNT_ERROR))
if return_data.get("invalid_subdomain"):
logging.warning("User %s attempted to password login to wrong subdomain %s" %

View File

@@ -55,7 +55,7 @@ from zproject.backends import ZulipDummyBackend, EmailAuthBackend, \
dev_auth_enabled, password_auth_enabled, github_auth_enabled, \
require_email_format_usernames, AUTH_BACKEND_NAME_MAP, \
ZulipLDAPConfigurationError, ZulipLDAPExceptionOutsideDomain, \
ZulipLDAPException, query_ldap, sync_user_from_ldap
ZulipLDAPException, query_ldap, sync_user_from_ldap, SocialAuthMixin
from zerver.views.auth import (maybe_send_to_registration,
_subdomain_token_salt)
@@ -94,7 +94,17 @@ class AuthBackendTest(ZulipTestCase):
# Verify auth fails with a deactivated user
do_deactivate_user(user_profile)
self.assertIsNone(backend.authenticate(**good_kwargs))
result = backend.authenticate(**good_kwargs)
if isinstance(backend, SocialAuthMixin):
# Returns a redirect to login page with an error.
self.assertEqual(result.status_code, 302)
self.assertEqual(result.url, "/accounts/login/?is_deactivated=true")
else:
# Just takes you back to the login page treating as
# invalid auth; this is correct because the form will
# provide the appropriate validation error for deactivated
# account.
self.assertIsNone(result)
# Reactivate the user and verify auth works again
do_reactivate_user(user_profile)
@@ -571,7 +581,7 @@ class SocialAuthBase(ZulipTestCase):
result = self.social_auth_test(account_data_dict,
subdomain='zulip')
self.assertEqual(result.status_code, 302)
self.assertEqual(result.url, "/login/")
self.assertEqual(result.url, "/accounts/login/?is_deactivated=true")
# TODO: verify whether we provide a clear error message
def test_social_auth_invalid_realm(self) -> None:

View File

@@ -23,7 +23,8 @@ from confirmation.models import Confirmation, create_confirmation_link
from zerver.context_processors import zulip_default_context, get_realm_from_request, \
login_context
from zerver.forms import HomepageForm, OurAuthenticationForm, \
WRONG_SUBDOMAIN_ERROR, ZulipPasswordResetForm, AuthenticationTokenForm
WRONG_SUBDOMAIN_ERROR, DEACTIVATED_ACCOUNT_ERROR, ZulipPasswordResetForm, \
AuthenticationTokenForm
from zerver.lib.mobile_auth_otp import is_valid_otp, otp_encrypt_api_key
from zerver.lib.push_notifications import push_notifications_enabled
from zerver.lib.request import REQ, has_request_variables, JsonableError
@@ -613,12 +614,13 @@ def add_dev_login_context(realm: Realm, context: Dict[str, Any]) -> None:
context['direct_users'] = [u for u in users if not (u.is_realm_admin or u.is_guest)]
def update_login_page_context(request: HttpRequest, context: Dict[str, Any]) -> None:
for key in ('email', 'subdomain', 'already_registered'):
for key in ('email', 'subdomain', 'already_registered', 'is_deactivated'):
try:
context[key] = request.GET[key]
except KeyError:
pass
context['deactivated_account_error'] = DEACTIVATED_ACCOUNT_ERROR
context['wrong_subdomain_error'] = WRONG_SUBDOMAIN_ERROR
class TwoFactorLoginView(BaseTwoFactorLoginView):

View File

@@ -21,7 +21,8 @@ from django.contrib.auth.backends import RemoteUserBackend
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.http import HttpResponse
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from requests import HTTPError
from social_core.backends.github import GithubOAuth2, GithubOrganizationOAuth2, \
GithubTeamOAuth2
@@ -636,6 +637,11 @@ class DevAuthBackend(ZulipAuthMixin):
return None
return common_get_active_user(dev_auth_username, realm, return_data=return_data)
def redirect_deactivated_user_to_login() -> HttpResponseRedirect:
login_url = reverse('django.contrib.auth.views.login')
redirect_url = login_url + '?is_deactivated=true'
return HttpResponseRedirect(redirect_url)
def social_associate_user_helper(backend: BaseAuth, return_data: Dict[str, Any],
*args: Any, **kwargs: Any) -> Optional[UserProfile]:
"""Responsible for doing the Zulip-account lookup and validation parts
@@ -751,7 +757,11 @@ def social_auth_finish(backend: Any,
if invalid_realm:
from zerver.views.auth import redirect_to_subdomain_login_url
return redirect_to_subdomain_login_url()
if auth_backend_disabled or inactive_user or inactive_realm or no_verified_email:
if inactive_user:
return redirect_deactivated_user_to_login()
if auth_backend_disabled or inactive_realm or no_verified_email:
# Redirect to login page. We can't send to registration
# workflow with these errors. We will redirect to login page.
return None