Add GitHub authentication.

Fixes: #1042
This commit is contained in:
Umair Khan 2016-07-20 16:33:27 +05:00 committed by Tim Abbott
parent d9b5f3089b
commit 80d62de40a
4 changed files with 70 additions and 1 deletions

View File

@ -2,7 +2,8 @@ from __future__ import absolute_import
from django.conf import settings
import ujson
from zproject.backends import password_auth_enabled, dev_auth_enabled, google_auth_enabled
from zproject.backends import (password_auth_enabled, dev_auth_enabled,
google_auth_enabled, github_auth_enabled)
def add_settings(request):
realm = request.user.realm if hasattr(request.user, "realm") else None
@ -28,6 +29,7 @@ def add_settings(request):
'password_auth_enabled': password_auth_enabled(realm),
'dev_auth_enabled': dev_auth_enabled(),
'google_auth_enabled': google_auth_enabled(),
'github_auth_enabled': github_auth_enabled(),
'development_environment': settings.DEVELOPMENT,
}

View File

@ -13,6 +13,8 @@ from zerver.models import UserProfile, Realm, get_user_profile_by_id, \
from apiclient.sample_tools import client as googleapiclient
from oauth2client.crypt import AppIdentityError
from social.backends.github import GithubOAuth2
from django.contrib.auth import authenticate
def password_auth_enabled(realm):
if realm is not None:
@ -55,6 +57,12 @@ def common_get_active_user_by_email(email, return_data=None):
return None
return user_profile
def github_auth_enabled():
for backend in django.contrib.auth.get_backends():
if isinstance(backend, GitHubBackend):
return True
return False
class ZulipAuthMixin(object):
def get_user(self, user_profile_id):
""" Get a UserProfile object from the user_profile_id. """
@ -208,3 +216,51 @@ class DevAuthBackend(ZulipAuthMixin):
def authenticate(self, username, return_data=None):
return common_get_active_user_by_email(username, return_data=return_data)
class GitHubBackend(ZulipAuthMixin, GithubOAuth2):
def authenticate(self, *args, **kwargs):
try:
email_address = kwargs['response']['email']
return_data = kwargs['return_data']
except KeyError:
return None
try:
user_profile = get_user_profile_by_email(email_address)
except UserProfile.DoesNotExist:
return_data["valid_attestation"] = True
return None
if not user_profile.is_active:
return_data["inactive_user"] = True
return None
if user_profile.realm.deactivated:
return_data["inactive_realm"] = True
return None
return user_profile
def do_auth(self, *args, **kwargs):
# This function needs to be imported from here due to the cyclic
# dependency.
from zerver.views import login_or_register_remote_user
kwargs['return_data'] = {}
user_profile = super(GitHubBackend, self).do_auth(*args, **kwargs)
return_data = kwargs['return_data']
inactive_user = return_data.get('inactive_user')
inactive_realm = return_data.get('inactive_realm')
if inactive_user or inactive_realm:
return None
request = self.strategy.request
details = kwargs['response']
email_address = details.get('email')
full_name = details.get('name')
return login_or_register_remote_user(request, email_address,
user_profile, full_name)

View File

@ -964,6 +964,14 @@ if POPULATE_PROFILE_VIA_LDAP and \
else:
POPULATE_PROFILE_VIA_LDAP = 'zproject.backends.ZulipLDAPAuthBackend' in AUTHENTICATION_BACKENDS or POPULATE_PROFILE_VIA_LDAP
########################################################################
# GITHUB AUTHENTICATION SETTINGS
########################################################################
SOCIAL_AUTH_GITHUB_KEY = get_secret('social_auth_github_key')
SOCIAL_AUTH_GITHUB_SECRET = get_secret('social_auth_github_secret')
SOCIAL_AUTH_LOGIN_ERROR_URL = '/login/'
SOCIAL_AUTH_GITHUB_SCOPE = ['email']
########################################################################
# EMAIL SETTINGS
########################################################################

View File

@ -310,6 +310,9 @@ urls += [
url(r'^notify_tornado$', 'zerver.tornadoviews.notify'),
]
# Python Social Auth
urls += [url(r'^', include('social.apps.django_app.urls', namespace='social'))]
if settings.DEVELOPMENT:
urls += dev_urls.urls
i18n_urls += dev_urls.i18n_urls