github: Call the appropriate authenticate.

This commit makes sure that GitHubAuthBackend will only authenticate
using its own authenticate method. This is done by adding a new
Python Social Auth strategy which instead of calling authenticate
method of Django, calls the authenticate of the backend directly.

The problem this commit solves is that while authenticating through
GitHub backend, we were ending up getting authenticated through
ZulipDummyBackend. This might happen because the default strategy used
by Python Social Auth calls the authenticate method of Django which
iterates over all the backends and tries the authenticate methods
which match with the function arguments. The new strategy this commit
adds calls the authenticate method of GitHub backend directly which
makes sense because we already know that we want to authenticate with
GithHub.

The actual problem of why we are ending up on ZulipDummyBackend is
still a mystery because the function arguments passed to its
authenticate method are different. It shouldn't be called.
This commit is contained in:
Umair Khan 2017-04-14 13:02:19 +05:00 committed by Tim Abbott
parent 22e21cddcb
commit ab260731a9
3 changed files with 11 additions and 5 deletions

View File

@ -39,13 +39,12 @@ from zproject.backends import ZulipDummyBackend, EmailAuthBackend, \
GoogleMobileOauth2Backend, ZulipRemoteUserBackend, ZulipLDAPAuthBackend, \ GoogleMobileOauth2Backend, ZulipRemoteUserBackend, ZulipLDAPAuthBackend, \
ZulipLDAPUserPopulator, DevAuthBackend, GitHubAuthBackend, ZulipAuthMixin, \ ZulipLDAPUserPopulator, DevAuthBackend, GitHubAuthBackend, ZulipAuthMixin, \
dev_auth_enabled, password_auth_enabled, github_auth_enabled, \ dev_auth_enabled, password_auth_enabled, github_auth_enabled, \
SocialAuthMixin, AUTH_BACKEND_NAME_MAP SocialAuthMixin, AUTH_BACKEND_NAME_MAP, SocialAuthStrategy
from zerver.views.auth import maybe_send_to_registration from zerver.views.auth import maybe_send_to_registration
from version import ZULIP_VERSION from version import ZULIP_VERSION
from social_core.exceptions import AuthFailed, AuthStateForbidden from social_core.exceptions import AuthFailed, AuthStateForbidden
from social_django.strategy import DjangoStrategy
from social_django.storage import BaseDjangoStorage from social_django.storage import BaseDjangoStorage
from social_core.backends.github import GithubOrganizationOAuth2, GithubTeamOAuth2, \ from social_core.backends.github import GithubOrganizationOAuth2, GithubTeamOAuth2, \
GithubOAuth2 GithubOAuth2
@ -392,7 +391,7 @@ class GitHubAuthBackendTest(ZulipTestCase):
self.email = 'hamlet@zulip.com' self.email = 'hamlet@zulip.com'
self.name = 'Hamlet' self.name = 'Hamlet'
self.backend = GitHubAuthBackend() self.backend = GitHubAuthBackend()
self.backend.strategy = DjangoStrategy(storage=BaseDjangoStorage()) self.backend.strategy = SocialAuthStrategy(storage=BaseDjangoStorage())
self.user_profile = get_user_profile_by_email(self.email) self.user_profile = get_user_profile_by_email(self.email)
self.user_profile.backend = self.backend self.user_profile.backend = self.backend
@ -406,7 +405,7 @@ class GitHubAuthBackendTest(ZulipTestCase):
def do_auth(self, *args, **kwargs): def do_auth(self, *args, **kwargs):
# type: (*Any, **Any) -> UserProfile # type: (*Any, **Any) -> UserProfile
with self.settings(AUTHENTICATION_BACKENDS=('zproject.backends.GitHubAuthBackend',)): with self.settings(AUTHENTICATION_BACKENDS=('zproject.backends.GitHubAuthBackend',)):
return self.backend.authenticate(**kwargs) return self.backend.strategy.authenticate(self.backend, **kwargs)
def test_github_auth_enabled(self): def test_github_auth_enabled(self):
# type: () -> None # type: () -> None

View File

@ -17,6 +17,7 @@ from zerver.models import UserProfile, Realm, get_user_profile_by_id, \
from apiclient.sample_tools import client as googleapiclient from apiclient.sample_tools import client as googleapiclient
from oauth2client.crypt import AppIdentityError from oauth2client.crypt import AppIdentityError
from social_core.backends.base import BaseAuth
from social_core.backends.github import GithubOAuth2, GithubOrganizationOAuth2, \ from social_core.backends.github import GithubOAuth2, GithubOrganizationOAuth2, \
GithubTeamOAuth2 GithubTeamOAuth2
from social_core.exceptions import AuthFailed, SocialAuthBaseException from social_core.exceptions import AuthFailed, SocialAuthBaseException
@ -102,6 +103,11 @@ class ZulipAuthMixin(object):
except UserProfile.DoesNotExist: except UserProfile.DoesNotExist:
return None return None
class SocialAuthStrategy(DjangoStrategy):
def authenticate(self, backend, *args, **kwargs):
# type: (BaseAuth, *Any, **Any) -> None
return backend.authenticate(*args, **kwargs)
class SocialAuthMixin(ZulipAuthMixin): class SocialAuthMixin(ZulipAuthMixin):
auth_backend_name = None # type: Text auth_backend_name = None # type: Text
@ -116,7 +122,7 @@ class SocialAuthMixin(ZulipAuthMixin):
def authenticate(self, def authenticate(self,
realm_subdomain='', # type: Optional[Text] realm_subdomain='', # type: Optional[Text]
storage=None, # type: Optional[DjangoStorage] storage=None, # type: Optional[DjangoStorage]
strategy=None, # type: Optional[DjangoStrategy] strategy=None, # type: Optional[SocialAuthStrategy]
user=None, # type: Optional[Dict[str, Any]] user=None, # type: Optional[Dict[str, Any]]
return_data=None, # type: Optional[Dict[str, Any]] return_data=None, # type: Optional[Dict[str, Any]]
response=None, # type: Optional[Dict[str, Any]] response=None, # type: Optional[Dict[str, Any]]

View File

@ -1202,6 +1202,7 @@ SOCIAL_AUTH_GITHUB_ORG_KEY = SOCIAL_AUTH_GITHUB_KEY
SOCIAL_AUTH_GITHUB_ORG_SECRET = SOCIAL_AUTH_GITHUB_SECRET SOCIAL_AUTH_GITHUB_ORG_SECRET = SOCIAL_AUTH_GITHUB_SECRET
SOCIAL_AUTH_GITHUB_TEAM_KEY = SOCIAL_AUTH_GITHUB_KEY SOCIAL_AUTH_GITHUB_TEAM_KEY = SOCIAL_AUTH_GITHUB_KEY
SOCIAL_AUTH_GITHUB_TEAM_SECRET = SOCIAL_AUTH_GITHUB_SECRET SOCIAL_AUTH_GITHUB_TEAM_SECRET = SOCIAL_AUTH_GITHUB_SECRET
SOCIAL_AUTH_STRATEGY = 'zproject.backends.SocialAuthStrategy'
######################################################################## ########################################################################
# EMAIL SETTINGS # EMAIL SETTINGS