Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recalculate authenticated user on complete #651

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Changed
- Fixed Slack user identity API call with Bearer headers
- Fixed microsoft-graph login error
- Re-calculate whether the user is still authenticated after the pipeline in the `do_complete` function.


## [4.1.0](https://github.com/python-social-auth/social-core/releases/tag/4.1.0) - 2021-03-01
Expand Down
33 changes: 17 additions & 16 deletions social_core/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@ def do_complete(backend, login, user=None, redirect_name='next',
*args, **kwargs):
data = backend.strategy.request_data()

is_authenticated = user_is_authenticated(user)
user = user if is_authenticated else None
is_authenticated_pre_pipeline = user_is_authenticated(user)
pre_pipeline_user = user if is_authenticated_pre_pipeline else None

partial = partial_pipeline_data(backend, user, *args, **kwargs)
partial = partial_pipeline_data(backend, pre_pipeline_user, *args, **kwargs)
if partial:
user = backend.continue_pipeline(partial)
post_pipeline_user = backend.continue_pipeline(partial)
# clean partial data after usage
backend.strategy.clean_partial_pipeline(partial.token)
else:
user = backend.complete(user=user, *args, **kwargs)
post_pipeline_user = backend.complete(user=pre_pipeline_user, *args, **kwargs)

# pop redirect value before the session is trashed on login(), but after
# the pipeline so that the pipeline can change the redirect if needed
Expand All @@ -52,22 +52,23 @@ def do_complete(backend, login, user=None, redirect_name='next',
# check if the output value is something else than a user and just
# return it to the client
user_model = backend.strategy.storage.user.user_model()
if user and not isinstance(user, user_model):
return user
if post_pipeline_user and not isinstance(post_pipeline_user, user_model):
return post_pipeline_user

if is_authenticated:
if not user:
is_authenticated_post_pipeline = user_is_authenticated(post_pipeline_user)
if is_authenticated_post_pipeline:
if not post_pipeline_user:
url = setting_url(backend, redirect_value, 'LOGIN_REDIRECT_URL')
else:
url = setting_url(backend, redirect_value,
'NEW_ASSOCIATION_REDIRECT_URL',
'LOGIN_REDIRECT_URL')
elif user:
if user_is_active(user):
elif post_pipeline_user:
if user_is_active(post_pipeline_user):
# catch is_new/social_user in case login() resets the instance
is_new = getattr(user, 'is_new', False)
social_user = user.social_user
login(backend, user, social_user)
is_new = getattr(post_pipeline_user, 'is_new', False)
social_user = post_pipeline_user.social_user
login(backend, post_pipeline_user, social_user)
# store last login backend name in session
backend.strategy.session_set('social_auth_last_login_backend',
social_user.provider)
Expand All @@ -82,8 +83,8 @@ def do_complete(backend, login, user=None, redirect_name='next',
'LOGIN_REDIRECT_URL')
else:
if backend.setting('INACTIVE_USER_LOGIN', False):
social_user = user.social_user
login(backend, user, social_user)
social_user = post_pipeline_user.social_user
login(backend, post_pipeline_user, social_user)
url = setting_url(backend, 'INACTIVE_USER_URL', 'LOGIN_ERROR_URL',
'LOGIN_URL')
else:
Expand Down
8 changes: 8 additions & 0 deletions social_core/tests/actions/test_login.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@


class LoginActionTest(BaseActionTest):
def setUp(self):
super().setUp()
User.set_authenticated(False)

def tearDown(self):
super().tearDown()
User.set_authenticated(True)

def test_login(self):
self.do_login()

Expand Down
8 changes: 8 additions & 0 deletions social_core/tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class User(BaseModel):
NEXT_ID = 1
cache = {}
_is_active = True
_is_authenticated = True

def __init__(self, username, email=None, **extra_user_fields):
self.id = User.next_id()
Expand All @@ -39,10 +40,17 @@ def __init__(self, username, email=None, **extra_user_fields):
def is_active(self):
return self._is_active

def is_authenticated(self):
return self._is_authenticated

@classmethod
def set_active(cls, is_active=True):
cls._is_active = is_active

@classmethod
def set_authenticated(cls, is_authenticated=True):
cls._is_authenticated = is_authenticated

def set_password(self, password):
self.password = password

Expand Down