Commit 90cdb913 by Braden MacDonald

Allow users to login via third_party_auth even if not activated

parent 08087861
......@@ -151,19 +151,6 @@ class AuthEntryError(AuthException):
"""
class NotActivatedException(AuthException):
""" Raised when a user tries to login to an unverified account """
def __init__(self, backend, email):
self.email = email
super(NotActivatedException, self).__init__(backend, email)
def __str__(self):
return (
_('This account has not yet been activated. An activation email has been re-sent to {email_address}.')
.format(email_address=self.email)
)
class ProviderUserState(object):
"""Object representing the provider state (attached or not) for a user.
......@@ -514,26 +501,24 @@ def ensure_user_information(strategy, auth_entry, backend=None, user=None, socia
# This parameter is used by the auth_exchange app, which always allows users to
# login, whether or not their account is validated.
pass
# IF the user has just registered a new account as part of this pipeline, that is fine
# and we allow the login to continue this once, because if we pause again to force the
# user to activate their account via email, the pipeline may get lost (e.g. email takes
# too long to arrive, user opens the activation email on a different device, etc.).
# This is consistent with first party auth and ensures that the pipeline completes
# fully, which is critical.
# But if this is an existing account, we refuse to allow them to login again until they
# check their email and activate the account.
elif social is not None:
# This third party account is already linked to a user account. That means that the
# user's account existed before this pipeline originally began (since the creation
# of the 'social' link entry occurs in one of the following pipeline steps).
# Reject this login attempt and tell the user to validate their account first.
# Send them another activation email:
student.views.reactivation_email_for_user(user)
raise NotActivatedException(backend, user.email)
# else: The user must have just successfully registered their account, so we proceed.
# We know they did not just login, because the login process rejects unverified users.
elif social is None:
# The user has just registered a new account as part of this pipeline. Their account
# is inactive but we allow the login to continue, because if we pause again to force
# the user to activate their account via email, the pipeline may get lost (e.g.
# email takes too long to arrive, user opens the activation email on a different
# device, etc.). This is consistent with first party auth and ensures that the
# pipeline completes fully, which is critical.
pass
else:
# This is an existing account, linked to a third party provider but not activated.
# We now also allow them to login again, because if they had entered their email
# incorrectly then there would be no way for them to recover the account, nor
# register anew via SSO. See SOL-1324 in JIRA.
# However, we will log a warning for this case:
logger.warning(
'User "%s" is using third_party_auth to login but has not yet activated their account. ',
user.username
)
@partial.partial
......
......@@ -73,11 +73,10 @@ def apply_settings(django_settings):
django_settings.SOCIAL_AUTH_RAISE_EXCEPTIONS = False
# Allow users to login using social auth even if their account is not verified yet
# The 'ensure_user_information' step controls this and only allows brand new users
# to login without verification. Repeat logins are not permitted until the account
# gets verified.
django_settings.INACTIVE_USER_LOGIN = True
django_settings.INACTIVE_USER_URL = '/auth/inactive'
# Otherwise users who use social auth to register with an invalid email address
# can become "stuck". We control this in a more fine-grained manner in pipeline.py
django_settings.SOCIAL_AUTH_INACTIVE_USER_LOGIN = True
django_settings.SOCIAL_AUTH_INACTIVE_USER_URL = '/auth/inactive'
# Context processors required under Django.
django_settings.SOCIAL_AUTH_UUID_LENGTH = 4
......
......@@ -17,8 +17,13 @@ URL_NAMESPACE = getattr(settings, setting_name('URL_NAMESPACE'), None) or 'socia
def inactive_user_view(request):
"""
A newly registered user has completed the social auth pipeline.
Their account is not yet activated, but we let them login this once.
A newly or recently registered user has completed the social auth pipeline.
Their account is not yet activated, but we let them login since the third party auth
provider is trusted to vouch for them. See details in pipeline.py.
The reason this view exists is that if we don't define this as the
SOCIAL_AUTH_INACTIVE_USER_URL, inactive users will get sent to LOGIN_ERROR_URL, which we
don't want.
"""
# 'next' may be set to '/account/finish_auth/.../' if this user needs to be auto-enrolled
# in a course. Otherwise, just redirect them to the dashboard, which displays a message
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment