diff --git a/helios_auth/auth_systems/__init__.py b/helios_auth/auth_systems/__init__.py index 84382e84a4f394b8e16c1d326d637f9dedf18c55..181834137a187acd82058c00098166d5786c3710 100644 --- a/helios_auth/auth_systems/__init__.py +++ b/helios_auth/auth_systems/__init__.py @@ -1,5 +1,5 @@ from django.conf import settings -from . import password, twitter, linkedin, cas, facebook, google, yahoo, clever +from . import password, twitter, linkedin, cas, facebook, google, yahoo, clever, github AUTH_SYSTEMS = {} @@ -11,6 +11,7 @@ AUTH_SYSTEMS['facebook'] = facebook AUTH_SYSTEMS['google'] = google AUTH_SYSTEMS['yahoo'] = yahoo AUTH_SYSTEMS['clever'] = clever +AUTH_SYSTEMS['github'] = github # not ready #import live diff --git a/helios_auth/auth_systems/github.py b/helios_auth/auth_systems/github.py new file mode 100644 index 0000000000000000000000000000000000000000..30c0e82024ff974c2d59c0619734ee2a5f6fb166 --- /dev/null +++ b/helios_auth/auth_systems/github.py @@ -0,0 +1,90 @@ +""" +Github Authentication + +""" + +import httplib2 +from django.conf import settings +from django.core.mail import send_mail +from oauth2client.client import OAuth2WebServerFlow + +from helios_auth import utils + +# some parameters to indicate that status updating is not possible +STATUS_UPDATES = False + +# display tweaks +LOGIN_MESSAGE = "Log in with GitHub" + +def get_flow(redirect_url=None): + return OAuth2WebServerFlow( + client_id=settings.GH_CLIENT_ID, + client_secret=settings.GH_CLIENT_SECRET, + scope='read:user user:email', + auth_uri="https://github.com/login/oauth/authorize", + token_uri="https://github.com/login/oauth/access_token", + redirect_uri=redirect_url, + ) + +def get_auth_url(request, redirect_url): + flow = get_flow(redirect_url) + request.session['gh_redirect_uri'] = redirect_url + return flow.step1_get_authorize_url() + +def get_user_info_after_auth(request): + redirect_uri = request.session['gh_redirect_uri'] + del request.session['gh_redirect_uri'] + flow = get_flow(redirect_uri) + if 'code' not in request.GET: + return None + code = request.GET['code'] + credentials = flow.step2_exchange(code) + + http = httplib2.Http(".cache") + http = credentials.authorize(http) + (_, content) = http.request("https://api.github.com/user", "GET") + response = utils.from_json(content.decode('utf-8')) + user_id = response['login'] + user_name = response['name'] + + (_, content) = http.request("https://api.github.com/user/emails", "GET") + response = utils.from_json(content.decode('utf-8')) + user_email = None + for email in response: + if email['verified'] and email['primary']: + user_email = email['email'] + break + if not user_email: + raise Exception("email address with GitHub not verified") + + return { + 'type': 'github', + 'user_id': user_id, + 'name': '%s (%s)' % (user_id, user_name), + 'info': {'email': user_email}, + 'token': {}, + } + +def do_logout(user): + return None + +def update_status(token, message): + pass + +def send_message(user_id, name, user_info, subject, body): + send_mail( + subject, + body, + settings.SERVER_EMAIL, + ["%s <%s>" % (user_id, user_info['email'])], + fail_silently=False, + ) + +def check_constraint(eligibility, user_info): + pass + +# +# Election Creation +# +def can_create_election(user_id, user_info): + return True diff --git a/helios_auth/media/login-icons/github.png b/helios_auth/media/login-icons/github.png new file mode 100644 index 0000000000000000000000000000000000000000..182a1a3f734fc1b7d712c68b04c29bad9460d6cd Binary files /dev/null and b/helios_auth/media/login-icons/github.png differ diff --git a/settings.py b/settings.py index f4dddc3bd18e1466f77c5ccb6b1eddaace743d6b..b22c94ffa85951fe42f3c36aa5bbb2a5a2d647c6 100644 --- a/settings.py +++ b/settings.py @@ -246,6 +246,10 @@ CAS_ELIGIBILITY_REALM = get_from_env('CAS_ELIGIBILITY_REALM', "") CLEVER_CLIENT_ID = get_from_env('CLEVER_CLIENT_ID', "") CLEVER_CLIENT_SECRET = get_from_env('CLEVER_CLIENT_SECRET', "") +# GitHub +GH_CLIENT_ID = get_from_env('GH_CLIENT_ID', '') +GH_CLIENT_SECRET = get_from_env('GH_CLIENT_SECRET', '') + # email server EMAIL_HOST = get_from_env('EMAIL_HOST', 'localhost') EMAIL_PORT = int(get_from_env('EMAIL_PORT', "2525"))