From 704bc18e76ac025b2a064984a10f9136757a5769 Mon Sep 17 00:00:00 2001 From: Corey Shields Date: Sat, 17 Nov 2018 15:11:35 -0500 Subject: [PATCH] initial auth0 support for db --- auth0login/__init__.py | 0 auth0login/admin.py | 6 ++++ auth0login/apps.py | 8 ++++++ auth0login/auth0backend.py | 35 +++++++++++++++++++++++ auth0login/migrations/__init__.py | 0 auth0login/models.py | 6 ++++ auth0login/tests.py | 6 ++++ auth0login/urls.py | 8 ++++++ auth0login/views.py | 7 +++++ db/base/context_processors.py | 8 ++++++ db/settings.py | 40 ++++++++++++++++++++++++++- db/templates/base.html | 3 +- db/templates/includes/auth_auth0.html | 1 + db/templates/includes/auth_local.html | 2 ++ db/urls.py | 6 ++++ requirements.txt | 2 ++ 16 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 auth0login/__init__.py create mode 100644 auth0login/admin.py create mode 100644 auth0login/apps.py create mode 100644 auth0login/auth0backend.py create mode 100644 auth0login/migrations/__init__.py create mode 100644 auth0login/models.py create mode 100644 auth0login/tests.py create mode 100644 auth0login/urls.py create mode 100644 auth0login/views.py create mode 100644 db/templates/includes/auth_auth0.html create mode 100644 db/templates/includes/auth_local.html diff --git a/auth0login/__init__.py b/auth0login/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/auth0login/admin.py b/auth0login/admin.py new file mode 100644 index 0000000..a3846a1 --- /dev/null +++ b/auth0login/admin.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +# from django.contrib import admin + +# Register your models here. diff --git a/auth0login/apps.py b/auth0login/apps.py new file mode 100644 index 0000000..513c748 --- /dev/null +++ b/auth0login/apps.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class Auth0LoginConfig(AppConfig): + name = 'auth0login' diff --git a/auth0login/auth0backend.py b/auth0login/auth0backend.py new file mode 100644 index 0000000..72a217e --- /dev/null +++ b/auth0login/auth0backend.py @@ -0,0 +1,35 @@ +import requests +from social_core.backends.oauth import BaseOAuth2 + + +class Auth0(BaseOAuth2): + """Auth0 OAuth authentication backend""" + name = 'auth0' + SCOPE_SEPARATOR = ' ' + ACCESS_TOKEN_METHOD = 'POST' + EXTRA_DATA = [ + ('email', 'email') + ] + + def authorization_url(self): + """Return the authorization endpoint.""" + return "https://" + self.setting('DOMAIN') + "/authorize" + + def access_token_url(self): + """Return the token endpoint.""" + return "https://" + self.setting('DOMAIN') + "/oauth/token" + + def get_user_id(self, details, response): + """Return current user id.""" + return details['user_id'] + + def get_user_details(self, response): + url = 'https://' + self.setting('DOMAIN') + '/userinfo' + headers = {'authorization': 'Bearer ' + response['access_token']} + resp = requests.get(url, headers=headers) + userinfo = resp.json() + + return {'username': userinfo['nickname'], + 'email': userinfo['email'], + # 'first_name': userinfo['name'], + 'user_id': userinfo['sub']} diff --git a/auth0login/migrations/__init__.py b/auth0login/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/auth0login/models.py b/auth0login/models.py new file mode 100644 index 0000000..1e8e4e1 --- /dev/null +++ b/auth0login/models.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +# from django.db import models + +# Create your models here. diff --git a/auth0login/tests.py b/auth0login/tests.py new file mode 100644 index 0000000..c2de5b3 --- /dev/null +++ b/auth0login/tests.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +# from django.test import TestCase + +# Create your tests here. diff --git a/auth0login/urls.py b/auth0login/urls.py new file mode 100644 index 0000000..2272e71 --- /dev/null +++ b/auth0login/urls.py @@ -0,0 +1,8 @@ +from django.conf.urls import url, include +from . import views + +urlpatterns = [ + url('^$', views.index), + url(r'^', include('django.contrib.auth.urls', namespace='auth')), + url(r'^', include('social_django.urls', namespace='social')), +] diff --git a/auth0login/views.py b/auth0login/views.py new file mode 100644 index 0000000..a08b706 --- /dev/null +++ b/auth0login/views.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +from django.shortcuts import render + + +def index(request): + return render(request, 'index.html') diff --git a/db/base/context_processors.py b/db/base/context_processors.py index f169bf8..bf685fe 100644 --- a/db/base/context_processors.py +++ b/db/base/context_processors.py @@ -16,3 +16,11 @@ def stage_notice(request): return {'stage_notice': render_to_string('includes/stage_notice.html')} else: return {'stage_notice': ''} + + +def auth_block(request): + """Displays auth links local vs auth0.""" + if settings.AUTH0: + return {'auth_block': render_to_string('includes/auth_auth0.html')} + else: + return {'auth_block': render_to_string('includes/auth_local.html')} diff --git a/db/settings.py b/db/settings.py index eb3a4b7..7445222 100644 --- a/db/settings.py +++ b/db/settings.py @@ -7,6 +7,7 @@ ROOT = Path(__file__).parent ENVIRONMENT = config('ENVIRONMENT', default='production') DEBUG = config('DEBUG', default=False, cast=bool) +AUTH0 = config('AUTH0', default=False, cast=bool) # Apps DJANGO_APPS = ( @@ -33,6 +34,11 @@ LOCAL_APPS = ( 'db.base', 'db.api', ) + +if AUTH0: + THIRD_PARTY_APPS += ('social_django',) + LOCAL_APPS += ('auth0login',) + INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS # Middlware @@ -101,6 +107,7 @@ TEMPLATES = [ 'django.template.context_processors.request', 'db.base.context_processors.analytics', 'db.base.context_processors.stage_notice', + 'db.base.context_processors.auth_block', ], 'loaders': [ ('django.template.loaders.cached.Loader', [ @@ -143,12 +150,16 @@ WSGI_APPLICATION = 'db.wsgi.application' # Auth AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', - 'allauth.account.auth_backends.AuthenticationBackend', ) +if AUTH0: + AUTHENTICATION_BACKENDS += ('auth0login.auth0backend.Auth0',) + ACCOUNT_AUTHENTICATION_METHOD = 'username' ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_EMAIL_VERIFICATION = 'mandatory' LOGIN_REDIRECT_URL = 'home' +LOGIN_URL = "/login/auth0" +LOGOUT_REDIRECT_URL = "/" # Logging LOGGING = { @@ -269,6 +280,33 @@ INFLUX_USER = config('INFLUX_USER', default='db') INFLUX_PASS = config('INFLUX_PASS', default='db') INFLUX_DB = config('INFLUX_DB', default='db') +if AUTH0: + SOCIAL_AUTH_TRAILING_SLASH = False # Remove end slash from routes + SOCIAL_AUTH_AUTH0_DOMAIN = config('SOCIAL_AUTH_AUTH0_DOMAIN', default='YOUR_AUTH0_DOMAIN') + SOCIAL_AUTH_AUTH0_KEY = config('SOCIAL_AUTH_AUTH0_KEY', default='YOUR_CLIENT_ID') + SOCIAL_AUTH_AUTH0_SECRET = config('SOCIAL_AUTH_AUTH0_SECRET', default='YOUR_CLIENT_SECRET') + SOCIAL_AUTH_REDIRECT_IS_HTTPS = True + SOCIAL_AUTH_PROTECTED_USER_FIELDS = ['email', 'first_name', 'last_name'] + + SOCIAL_AUTH_PIPELINE = ( + 'social_core.pipeline.social_auth.social_details', + 'social_core.pipeline.social_auth.social_uid', + 'social_core.pipeline.social_auth.auth_allowed', + 'social_core.pipeline.social_auth.social_user', + 'social_core.pipeline.social_auth.associate_by_email', + 'social_core.pipeline.user.get_username', + 'social_core.pipeline.user.create_user', + 'social_core.pipeline.social_auth.associate_user', + 'social_core.pipeline.social_auth.load_extra_data', + 'social_core.pipeline.user.user_details', + ) + + SOCIAL_AUTH_AUTH0_SCOPE = [ + 'openid', + 'email', + 'profile', + ] + if ENVIRONMENT == 'dev': # Disable template caching for backend in TEMPLATES: diff --git a/db/templates/base.html b/db/templates/base.html index 10baefb..7436926 100644 --- a/db/templates/base.html +++ b/db/templates/base.html @@ -59,8 +59,7 @@ {% else %} -
  • Sign Up
  • -
  • Log In
  • + {{ auth_block }} {% endif %} diff --git a/db/templates/includes/auth_auth0.html b/db/templates/includes/auth_auth0.html new file mode 100644 index 0000000..e26810d --- /dev/null +++ b/db/templates/includes/auth_auth0.html @@ -0,0 +1 @@ +
  • Sign Up / Log In
  • diff --git a/db/templates/includes/auth_local.html b/db/templates/includes/auth_local.html new file mode 100644 index 0000000..304bb86 --- /dev/null +++ b/db/templates/includes/auth_local.html @@ -0,0 +1,2 @@ +
  • Sign Up
  • +
  • Log In
  • diff --git a/db/urls.py b/db/urls.py index ab4cced..d7a9f81 100644 --- a/db/urls.py +++ b/db/urls.py @@ -25,6 +25,12 @@ urlpatterns = [ url(r'^admin/', admin.site.urls), ] +# Auth0 +if settings.AUTH0: + urlpatterns += [ + url(r'^', include('auth0login.urls')) + ] + if settings.DEBUG: urlpatterns += [ url(r'^media/(?P.*)$', serve, diff --git a/requirements.txt b/requirements.txt index 76f9f7b..3ca8bd2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -35,6 +35,7 @@ Pillow==5.0.0 pyephem==3.7.6.0 python-dateutil==2.7.3 python-decouple==3.1 +python-dotenv==0.6.5 python-openid==2.2.5 pytool==3.10.0 pytz==2018.3 @@ -48,6 +49,7 @@ satnogsdecoders==0.1 shortuuid==0.5.0 simplejson==3.16.0 six==1.11.0 +social-auth-app-django==1.2.0 Unipath==1.1 urllib3==1.22 vine==1.1.4