[Python-modules-commits] [python-social-auth] 09/131: Fixes bug where partial pipelines from abandoned login attempts will be resumed on new login attempts. This can happen with the email backend, which sends data directly to auth:complete, thereby bypassing the call to `clean_partial_pipeline` in `do_auth`.

Wolfgang Borgert debacle at moszumanska.debian.org
Sat Dec 24 15:16:55 UTC 2016


This is an automated email from the git hooks/post-receive script.

debacle pushed a commit to tag v0.2.20
in repository python-social-auth.

commit 7da22bfe2106b6041b4ac72dda177ff732291fc2
Author: Sean Hayes <gasphynx at gmail.com>
Date:   Thu Mar 31 15:41:54 2016 -0700

    Fixes bug where partial pipelines from abandoned login attempts will be resumed on new login attempts. This can happen with the email backend, which sends data directly to auth:complete, thereby bypassing the call to `clean_partial_pipeline` in `do_auth`.
---
 social/tests/test_utils.py | 28 ++++++++++++++++++++++++++++
 social/utils.py            | 17 +++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/social/tests/test_utils.py b/social/tests/test_utils.py
index 7bd8db0..28d595e 100644
--- a/social/tests/test_utils.py
+++ b/social/tests/test_utils.py
@@ -121,6 +121,30 @@ class BuildAbsoluteURITest(unittest.TestCase):
 
 
 class PartialPipelineData(unittest.TestCase):
+    def test_returns_partial_when_uid_and_email_do_match(self):
+        email = 'foo at example.com'
+        backend = self._backend({'uid': email})
+        backend.strategy.request_data.return_value = {
+            backend.ID_KEY: email
+        }
+        key, val = ('foo', 'bar')
+        _, xkwargs = partial_pipeline_data(backend, None,
+                                           *(), **dict([(key, val)]))
+        self.assertTrue(key in xkwargs)
+        self.assertEqual(xkwargs[key], val)
+        self.assertEqual(backend.strategy.clean_partial_pipeline.call_count, 0)
+
+    def test_clean_pipeline_when_uid_does_not_match(self):
+        backend = self._backend({'uid': 'foo at example.com'})
+        backend.strategy.request_data.return_value = {
+            backend.ID_KEY: 'bar at example.com'
+        }
+        key, val = ('foo', 'bar')
+        ret = partial_pipeline_data(backend, None,
+                                           *(), **dict([(key, val)]))
+        self.assertIsNone(ret)
+        self.assertEqual(backend.strategy.clean_partial_pipeline.call_count, 1)
+
     def test_kwargs_included_in_result(self):
         backend = self._backend()
         key, val = ('foo', 'bar')
@@ -128,6 +152,7 @@ class PartialPipelineData(unittest.TestCase):
                                            *(), **dict([(key, val)]))
         self.assertTrue(key in xkwargs)
         self.assertEqual(xkwargs[key], val)
+        self.assertEqual(backend.strategy.clean_partial_pipeline.call_count, 0)
 
     def test_update_user(self):
         user = object()
@@ -135,15 +160,18 @@ class PartialPipelineData(unittest.TestCase):
         _, xkwargs = partial_pipeline_data(backend, user)
         self.assertTrue('user' in xkwargs)
         self.assertEqual(xkwargs['user'], user)
+        self.assertEqual(backend.strategy.clean_partial_pipeline.call_count, 0)
 
     def _backend(self, session_kwargs=None):
         strategy = Mock()
         strategy.request = None
+        strategy.request_data.return_value = {}
         strategy.session_get.return_value = object()
         strategy.partial_from_session.return_value = \
             (0, 'mock-backend', [], session_kwargs or {})
 
         backend = Mock()
+        backend.ID_KEY = 'email'
         backend.name = 'mock-backend'
         backend.strategy = strategy
         return backend
diff --git a/social/utils.py b/social/utils.py
index 0a473af..37c04a8 100644
--- a/social/utils.py
+++ b/social/utils.py
@@ -166,7 +166,24 @@ def partial_pipeline_data(backend, user=None, *args, **kwargs):
     if partial:
         idx, backend_name, xargs, xkwargs = \
             backend.strategy.partial_from_session(partial)
+
+        partial_matches_request = False
+
         if backend_name == backend.name:
+            partial_matches_request = True
+
+            req_data = backend.strategy.request_data()
+            # Normally when resuming a pipeline, request_data will be empty. We
+            # only need to check for a uid match if new data was provided (i.e.
+            # if current request specifies the ID_KEY).
+            if backend.ID_KEY in req_data:
+                id_from_partial = xkwargs.get('uid')
+                id_from_request = req_data.get(backend.ID_KEY)
+
+                if id_from_partial != id_from_request:
+                    partial_matches_request = False
+
+        if partial_matches_request:
             kwargs.setdefault('pipeline_index', idx)
             if user:  # don't update user if it's None
                 kwargs.setdefault('user', user)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-social-auth.git



More information about the Python-modules-commits mailing list