├── example ├── __init__.py ├── app │ ├── __init__.py │ ├── models.py │ ├── mail.py │ ├── fixtures │ │ └── initial_data.json │ ├── utils.py │ ├── pipeline.py │ └── views.py ├── templates │ ├── validation_sent.html │ ├── email.html │ ├── demo_feature_2.html │ ├── local_links.html │ ├── demo_feature_5.html │ ├── demo_feature_3.html │ ├── demo_feature_1.html │ ├── base.html │ ├── require_password.html │ ├── email_signup.html │ ├── username_signup.html │ ├── demo_feature_4.html │ ├── social_links.html │ ├── user_details.html │ ├── demo_feature_6.html │ └── home.html ├── local_settings.py.template ├── wsgi.py ├── urls.py └── settings.py ├── requirements.txt ├── manage.py ├── .gitignore └── README.rst /example/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/app/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | django 2 | git+https://github.com/omab/python-social-auth.git@master 3 | -------------------------------------------------------------------------------- /example/templates/validation_sent.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | A email validation was sent to {{ email }}. 5 | {% endblock %} 6 | {% block home_link %}{% endblock %} 7 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == '__main__': 6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'example.settings') 7 | from django.core.management import execute_from_command_line 8 | execute_from_command_line(sys.argv) 9 | -------------------------------------------------------------------------------- /example/templates/email.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block content %} 5 |
6 | {% csrf_token %} 7 | 8 | 9 | 10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /example/templates/demo_feature_2.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block content %} 5 |
6 |

2. Connecting more than one social account to a local account

7 | {% include "social_links.html" %} 8 |
9 | 10 | {% include "user_details.html" %} 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /example/templates/local_links.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /example/templates/demo_feature_5.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block content %} 5 |
6 |

5. E-mail address verification flow

7 | 8 | 11 |
12 | 13 | {% include "user_details.html" %} 14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /example/templates/demo_feature_3.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block content %} 5 |
6 |

2. Disconnecting a social account -- requires setting a password if only the local account remain

7 | {% include "social_links.html" %} 8 |
9 | 10 | {% with show_disconnect=True %} 11 | {% include "user_details.html" %} 12 | {% endwith %} 13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /example/templates/demo_feature_1.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block content %} 5 |
6 |

1. Signup of both local and social accounts

7 | 8 |
9 |

Local

10 | {% include "local_links.html" %} 11 | 12 |

Social

13 | {% include "social_links.html" %} 14 |
15 |
16 | 17 | {% include "user_details.html" %} 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /example/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Python Social Auth - Allauth Flows Demo 5 | 6 | 7 | {% block content %}{% endblock %} 8 | 9 | {% block home_link %} 10 |

11 | Return to Index and reset all 12 | {% if user.is_authenticated %}or Logout{% endif %} 13 |

14 | {% endblock %} 15 | 16 | 17 | -------------------------------------------------------------------------------- /example/templates/require_password.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block content %} 5 |
6 |

Set a password

7 |
8 | {% csrf_token %} 9 | 10 | 11 | 12 |
13 |
14 | {% endblock %} 15 | {% block home_link %}{% endblock %} 16 | -------------------------------------------------------------------------------- /example/templates/email_signup.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block content %} 5 |
{% csrf_token %} 6 |

7 | 8 | 9 |

10 | 11 |

12 | 13 | 14 |

15 | 16 | 17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /example/templates/username_signup.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block content %} 5 |
{% csrf_token %} 6 |

7 | 8 | 9 |

10 | 11 |

12 | 13 | 14 |

15 | 16 | 17 |
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg 8 | *.egg-info 9 | dist 10 | build 11 | eggs 12 | parts 13 | bin 14 | var 15 | sdist 16 | develop-eggs 17 | .installed.cfg 18 | lib 19 | lib64 20 | 21 | # Installer logs 22 | pip-log.txt 23 | 24 | # Unit test / coverage reports 25 | .coverage 26 | .tox 27 | nosetests.xml 28 | 29 | # Translations 30 | *.mo 31 | 32 | # Mr Developer 33 | .mr.developer.cfg 34 | .project 35 | .pydevproject 36 | 37 | test.db 38 | local_settings.py 39 | sessions/ 40 | _build/ 41 | fabfile.py 42 | 43 | .DS_Store -------------------------------------------------------------------------------- /example/templates/demo_feature_4.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block content %} 5 |
6 |

4. Optional instant-signup for social accounts -- no questions asked

7 |

This is the default behavior of python-social-auth, no major difference with previous 8 | social signups in previous demos

9 | 10 |
11 |

Social

12 | {% include "social_links.html" %} 13 |
14 |
15 | 16 | {% include "user_details.html" %} 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /example/app/mail.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.core.mail import send_mail 3 | from django.core.urlresolvers import reverse 4 | 5 | 6 | def send_validation(strategy, backend, code): 7 | url = reverse('social:complete', args=(backend.name,)) + \ 8 | '?verification_code=' + code.code 9 | url = strategy.request.build_absolute_uri(url) 10 | send_mail('Validate your account', 11 | 'Validate your account {0}'.format(url), 12 | settings.EMAIL_FROM, 13 | [code.email], 14 | fail_silently=False) 15 | -------------------------------------------------------------------------------- /example/app/fixtures/initial_data.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "pk": 1, 4 | "model": "auth.user", 5 | "fields": { 6 | "username": "foobar", 7 | "first_name": "Foo", 8 | "last_name": "Bar", 9 | "is_active": true, 10 | "is_superuser": false, 11 | "is_staff": false, 12 | "last_login": "2014-01-04T18:49:50.929Z", 13 | "groups": [], 14 | "user_permissions": [], 15 | "password": "pbkdf2_sha256$12000$8dfkUIdrX0X2$6DO/xYbSWNIOTEewfstjRtltkTWTO4AoWbtTqm7bFFY=", 16 | "email": "foo@bar.com", 17 | "date_joined": "2014-01-04T18:35:18.205Z" 18 | } 19 | } 20 | ] 21 | -------------------------------------------------------------------------------- /example/templates/social_links.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /example/app/utils.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | 3 | from django.template import RequestContext 4 | from django.shortcuts import render_to_response 5 | from django.contrib.auth.models import User 6 | 7 | from social.apps.django_app.default.models import UserSocialAuth 8 | 9 | 10 | def render_to(tpl): 11 | def decorator(func): 12 | @wraps(func) 13 | def wrapper(request, *args, **kwargs): 14 | out = func(request, *args, **kwargs) or {} 15 | if isinstance(out, dict): 16 | out['request'] = request 17 | out = render_to_response(tpl, out, RequestContext(request)) 18 | return out 19 | return wrapper 20 | return decorator 21 | 22 | 23 | def clear_all_social_accounts(): 24 | for usa in UserSocialAuth.objects.all(): 25 | usa.delete() 26 | User.objects.exclude(username='foobar').delete() 27 | -------------------------------------------------------------------------------- /example/templates/user_details.html: -------------------------------------------------------------------------------- 1 | {% if user.is_authenticated %} 2 |
3 |

User details

4 |
5 |

You are logged in as {{ user.username }}!

6 |

Associated accounts:

7 | 23 |
24 |
25 | {% endif %} 26 | -------------------------------------------------------------------------------- /example/app/pipeline.py: -------------------------------------------------------------------------------- 1 | from django.template import RequestContext 2 | from django.shortcuts import render_to_response 3 | 4 | from social.pipeline.partial import partial 5 | 6 | 7 | @partial 8 | def password_check(strategy, user, *args, **kwargs): 9 | if not user.has_usable_password() and user.social_auth.count() == 1: 10 | if strategy.request.POST.get('password'): 11 | user.set_password(strategy.request.POST['password']) 12 | user.save() 13 | else: 14 | return render_to_response('require_password.html', { 15 | 'request': strategy.request, 16 | 'next': strategy.request.POST.get('next') or '' 17 | }, RequestContext(strategy.request)) 18 | 19 | 20 | def set_password(strategy, backend, user, response, is_new=False, 21 | *args, **kwargs): 22 | if backend.name in ('email', 'username') and is_new and \ 23 | response.get('password'): 24 | user.set_password(response['password']) 25 | user.save() 26 | -------------------------------------------------------------------------------- /example/local_settings.py.template: -------------------------------------------------------------------------------- 1 | # Fill the settings below 2 | 3 | ## 4 | # Social backends keys / secrets 5 | 6 | # Check docs at: 7 | # http://psa.matiasaguirre.net/docs/backends/google.html#google-oauth2 8 | SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '' 9 | SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '' 10 | 11 | # Check docs at: 12 | # http://psa.matiasaguirre.net/docs/backends/facebook.html#oauth2 13 | SOCIAL_AUTH_FACEBOOK_KEY = '' 14 | SOCIAL_AUTH_FACEBOOK_SECRET = '' 15 | 16 | # Check docs at: 17 | # http://psa.matiasaguirre.net/docs/backends/twitter.html 18 | SOCIAL_AUTH_TWITTER_KEY = '' 19 | SOCIAL_AUTH_TWITTER_SECRET = '' 20 | 21 | # Check docs at: 22 | # http://psa.matiasaguirre.net/docs/backends/reddit.html 23 | SOCIAL_AUTH_REDDIT_KEY = '' 24 | SOCIAL_AUTH_REDDIT_SECRET = '' 25 | 26 | ## 27 | # Email validation settings, docs at 28 | # https://docs.djangoproject.com/en/dev/topics/email/ 29 | EMAIL_USE_TLS = True 30 | EMAIL_HOST = 'smtp.gmail.com' 31 | EMAIL_HOST_USER = '@gmail.com' 32 | EMAIL_HOST_PASSWORD = '' 33 | EMAIL_PORT = 587 34 | EMAIL_FROM = '@gmail.com' 35 | -------------------------------------------------------------------------------- /example/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for dj project. 3 | 4 | This module contains the WSGI application used by Django's development server 5 | and any production WSGI deployments. It should expose a module-level variable 6 | named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover 7 | this application via the ``WSGI_APPLICATION`` setting. 8 | 9 | Usually you will have the standard Django WSGI application here, but it also 10 | might make sense to replace the whole Django WSGI application with a custom one 11 | that later delegates to the Django one. For example, you could introduce WSGI 12 | middleware here, or combine a Django application with an application of another 13 | framework. 14 | 15 | """ 16 | import os 17 | 18 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings") 19 | 20 | # This application object is used by any WSGI server configured to use this 21 | # file. This includes Django's development server, if the WSGI_APPLICATION 22 | # setting points here. 23 | from django.core.wsgi import get_wsgi_application 24 | application = get_wsgi_application() 25 | 26 | # Apply WSGI middleware here. 27 | # from helloworld.wsgi import HelloWorldApplication 28 | # application = HelloWorldApplication(application) 29 | -------------------------------------------------------------------------------- /example/templates/demo_feature_6.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block content %} 5 |
6 |

6. E-mail address management (multiple e-mail addresses, setting a primary)

7 |

This feature is partially supported since primary email flagging is not 8 | implemented in python-social-auth, but check how easy it's to do so

9 | 10 | 13 |
14 | 15 | {% if user.is_authenticated %} 16 |
17 |

User details

18 |
19 |

You are logged in as {{ user.username }}!

20 |

Associated emails:

21 |
    22 | {% for assoc in backends.associated %} 23 |
  • {{ assoc.uid }} ({% if assoc.extra_data.primary %}primary{% else %}make primary{% endif %})
  • 24 | {% empty %} 25 |
  • No emails associated
  • 26 | {% endfor %} 27 |
28 |
29 |
30 | {% endif %} 31 | 32 | {% endblock %} 33 | -------------------------------------------------------------------------------- /example/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import patterns, include, url 2 | 3 | 4 | urlpatterns = patterns('', 5 | url(r'^$', 'example.app.views.home', name='home'), 6 | url(r'^logout/$', 'django.contrib.auth.views.logout', name='logout', 7 | kwargs={'next_page': '/'}), 8 | url(r'^local-and-social-signup/$', 9 | 'example.app.views.demo_feature_1', 10 | name='demo_feature_1'), 11 | url(r'^connecting-more-than-one-social-account/$', 12 | 'example.app.views.demo_feature_2', 13 | name='demo_feature_2'), 14 | url(r'^disconnecting-a-social-account/$', 15 | 'example.app.views.demo_feature_3', 16 | name='demo_feature_3'), 17 | url(r'^instant-signup/$', 18 | 'example.app.views.demo_feature_4', 19 | name='demo_feature_4'), 20 | url(r'^email-verification-flow/$', 21 | 'example.app.views.demo_feature_5', 22 | name='demo_feature_5'), 23 | url(r'^email-management/$', 24 | 'example.app.views.demo_feature_6', 25 | name='demo_feature_6'), 26 | 27 | url(r'^email-sent/$', 'example.app.views.validation_sent'), 28 | url(r'^email-primary/(?P\d+)/$', 'example.app.views.primary_email', 29 | name='primary_email'), 30 | 31 | url(r'', include('social.apps.django_app.urls', namespace='social')) 32 | ) 33 | -------------------------------------------------------------------------------- /example/app/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import redirect 2 | from django.contrib.auth import logout, login, authenticate 3 | from django.contrib.auth.decorators import login_required 4 | 5 | from .utils import render_to, clear_all_social_accounts 6 | 7 | 8 | @render_to('home.html') 9 | def home(request): 10 | # Ensure logged out session for propper demo testing 11 | if request.GET.get('reset') == '1': 12 | clear_all_social_accounts() 13 | if request.user.is_authenticated(): 14 | logout(request) 15 | 16 | 17 | @render_to('demo_feature_1.html') 18 | def demo_feature_1(request): 19 | pass 20 | 21 | 22 | @render_to('demo_feature_2.html') 23 | def demo_feature_2(request): 24 | # Login a local user (user is created if doesn't exists) 25 | user = authenticate(username='foobar', password='passwd') 26 | login(request, user) 27 | 28 | 29 | @render_to('demo_feature_3.html') 30 | def demo_feature_3(request): 31 | pass 32 | 33 | 34 | @render_to('demo_feature_4.html') 35 | def demo_feature_4(request): 36 | pass 37 | 38 | 39 | @render_to('demo_feature_5.html') 40 | def demo_feature_5(request): 41 | pass 42 | 43 | 44 | @render_to('demo_feature_6.html') 45 | def demo_feature_6(request): 46 | pass 47 | 48 | 49 | @render_to('validation_sent.html') 50 | def validation_sent(request): 51 | return {'email': request.session.get('email_validation_address')} 52 | 53 | 54 | @login_required 55 | def primary_email(request, usa_id): 56 | usa_id = int(usa_id) 57 | for usa in request.user.social_auth.filter(provider='email'): 58 | usa.set_extra_data({'primary': usa.id == usa_id}) 59 | usa.save() 60 | return redirect('demo_feature_6') 61 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Django-Allauth flows with python-social-auth 2 | ============================================ 3 | 4 | This is an small demo project looking to mimic django-allauth_ flows as they 5 | are detailed in `their docs`_ using python-social-auth_. This comes as an answer 6 | to a `request on reddit`_. 7 | 8 | Running the demos 9 | ----------------- 10 | 11 | The project is quite easy to setup once the dependencies are met. Follow these 12 | steps: 13 | 14 | * Clone the repository:: 15 | 16 | $ git clone https://github.com/omab/psa-allauth.git 17 | $ cd psa-allauth 18 | 19 | * Lets create a virtualenv_ (I'm using virtualenvwrapper_ here):: 20 | 21 | psa-allauth $ mkvirt demo 22 | [demo] psa-allauth $ 23 | 24 | * Install the dependencies (django_ and python-social-auth_):: 25 | 26 | [demo] psa-allauth $ pip install -r requirements.txt 27 | 28 | * Copy ``local_settings.py.template`` as ``local_settings.py`` and fill the 29 | blanks:: 30 | 31 | [demo] psa-allauth $ cp example/local_settings.py.template example/local_settings.py 32 | 33 | * Sync the database:: 34 | 35 | [demo] psa-allauth $ python manage.py syncdb --noinput 36 | 37 | * Run the demo:: 38 | 39 | [demo] psa-allauth $ python manage.py runserver 40 | 41 | * Open a browser at ``http://localhost:8000/`` and follow the instructions 42 | there. 43 | 44 | .. _django-allauth: https://github.com/pennersr/django-allauth 45 | .. _their docs: http://django-allauth.readthedocs.org/en/latest/overview.html#supported-flows 46 | .. _python-social-auth: https://github.com/omab/python-social-auth 47 | .. _request on reddit: http://www.reddit.com/r/django/comments/1u9nh9/modern_django_registration_packages/cegam4d 48 | .. _virtualenv: http://www.virtualenv.org/en/latest/ 49 | .. _virtualenvwrapper: http://virtualenvwrapper.readthedocs.org/en/latest/ 50 | .. _django: http://djangoproject.com/ 51 | -------------------------------------------------------------------------------- /example/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block content %} 5 |
6 |

Allauth supported flows

7 |
8 | From Django-Allauth Supported Flows 9 | these are the supported flows: 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
FeatureSupported by PSA?Demo
1Signup of both local and social accountsYesOpen
2Connecting more than one social account to a local accountYesOpen
3Disconnecting a social account -- requires setting a password if only the local account remainsYesOpen
4Optional instant-signup for social accounts -- no questions askedYesOpen
5E-mail address verification flowYesOpen
6E-mail address management (multiple e-mail addresses, setting a primary)PartialOpen
7Password forgotten flowNo
71 |
72 |
73 | {% endblock %} 74 | 75 | {% block home_link %}{% endblock %} 76 | -------------------------------------------------------------------------------- /example/settings.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from os.path import abspath, dirname, join 3 | 4 | 5 | sys.path.insert(0, '../..') 6 | 7 | DEBUG = True 8 | TEMPLATE_DEBUG = DEBUG 9 | 10 | ROOT_PATH = abspath(dirname(__file__)) 11 | 12 | ADMINS = ( 13 | # ('Your Name', 'your_email@example.com'), 14 | ) 15 | 16 | MANAGERS = ADMINS 17 | 18 | DATABASES = { 19 | 'default': { 20 | 'ENGINE': 'django.db.backends.sqlite3', 21 | 'NAME': 'test.db' 22 | } 23 | } 24 | 25 | TIME_ZONE = 'America/Montevideo' 26 | LANGUAGE_CODE = 'en-us' 27 | SITE_ID = 1 28 | USE_I18N = True 29 | USE_L10N = True 30 | USE_TZ = True 31 | MEDIA_ROOT = '' 32 | MEDIA_URL = '' 33 | 34 | STATIC_ROOT = '' 35 | STATIC_URL = '/static/' 36 | STATICFILES_DIRS = ( 37 | # Put strings here, like "/home/html/static" or "C:/www/django/static". 38 | # Always use forward slashes, even on Windows. 39 | # Don't forget to use absolute paths, not relative paths. 40 | ) 41 | STATICFILES_FINDERS = ( 42 | 'django.contrib.staticfiles.finders.FileSystemFinder', 43 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 44 | ) 45 | 46 | SECRET_KEY = '#$5btppqih8=%ae^#&7en#kyi!vh%he9rg=ed#hm6fnw9^=umc' 47 | 48 | TEMPLATE_LOADERS = ( 49 | 'django.template.loaders.filesystem.Loader', 50 | 'django.template.loaders.app_directories.Loader', 51 | ) 52 | 53 | MIDDLEWARE_CLASSES = ( 54 | 'django.middleware.common.CommonMiddleware', 55 | 'django.contrib.sessions.middleware.SessionMiddleware', 56 | 'django.middleware.csrf.CsrfViewMiddleware', 57 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 58 | 'django.contrib.messages.middleware.MessageMiddleware', 59 | # Uncomment the next line for simple clickjacking protection: 60 | # 'django.middleware.clickjacking.XFrameOptionsMiddleware', 61 | ) 62 | 63 | ROOT_URLCONF = 'example.urls' 64 | 65 | # Python dotted path to the WSGI application used by Django's runserver. 66 | WSGI_APPLICATION = 'example.wsgi.application' 67 | 68 | TEMPLATE_DIRS = ( 69 | join(ROOT_PATH, 'templates'), 70 | ) 71 | 72 | INSTALLED_APPS = ( 73 | 'django.contrib.auth', 74 | 'django.contrib.contenttypes', 75 | 'django.contrib.sessions', 76 | 'django.contrib.sites', 77 | 'django.contrib.messages', 78 | 'django.contrib.staticfiles', 79 | 'social.apps.django_app.default', 80 | 'example.app', 81 | ) 82 | 83 | LOGGING = { 84 | 'version': 1, 85 | 'disable_existing_loggers': False, 86 | 'filters': { 87 | 'require_debug_false': { 88 | '()': 'django.utils.log.RequireDebugFalse' 89 | } 90 | }, 91 | 'handlers': { 92 | 'mail_admins': { 93 | 'level': 'ERROR', 94 | 'filters': ['require_debug_false'], 95 | 'class': 'django.utils.log.AdminEmailHandler' 96 | } 97 | }, 98 | 'loggers': { 99 | 'django.request': { 100 | 'handlers': ['mail_admins'], 101 | 'level': 'ERROR', 102 | 'propagate': True, 103 | }, 104 | } 105 | } 106 | 107 | SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' 108 | 109 | TEMPLATE_CONTEXT_PROCESSORS = ( 110 | 'django.contrib.auth.context_processors.auth', 111 | 'django.core.context_processors.debug', 112 | 'django.core.context_processors.i18n', 113 | 'django.core.context_processors.media', 114 | 'django.contrib.messages.context_processors.messages', 115 | 'social.apps.django_app.context_processors.backends', 116 | ) 117 | 118 | AUTHENTICATION_BACKENDS = ( 119 | 'social.backends.google.GoogleOAuth2', 120 | 'social.backends.facebook.FacebookOAuth2', 121 | 'social.backends.reddit.RedditOAuth2', 122 | 'social.backends.twitter.TwitterOAuth', 123 | 'social.backends.email.EmailAuth', 124 | 'social.backends.username.UsernameAuth', 125 | 'django.contrib.auth.backends.ModelBackend', 126 | ) 127 | 128 | LOGIN_URL = '/' 129 | LOGIN_REDIRECT_URL = '/' 130 | URL_PATH = '' 131 | SOCIAL_AUTH_STRATEGY = 'social.strategies.django_strategy.DjangoStrategy' 132 | SOCIAL_AUTH_STORAGE = 'social.apps.django_app.default.models.DjangoStorage' 133 | SOCIAL_AUTH_GOOGLE_OAUTH_SCOPE = [ 134 | 'https://www.googleapis.com/auth/drive', 135 | 'https://www.googleapis.com/auth/userinfo.profile' 136 | ] 137 | 138 | SOCIAL_AUTH_EMAIL_VALIDATION_FUNCTION = 'example.app.mail.send_validation' 139 | SOCIAL_AUTH_EMAIL_VALIDATION_URL = '/email-sent/' 140 | SOCIAL_AUTH_EMAIL_FORM_HTML = 'email_signup.html' 141 | SOCIAL_AUTH_USERNAME_FORM_HTML = 'username_signup.html' 142 | 143 | SOCIAL_AUTH_PIPELINE = ( 144 | 'social.pipeline.social_auth.social_details', 145 | 'social.pipeline.social_auth.social_uid', 146 | 'social.pipeline.social_auth.auth_allowed', 147 | 'social.pipeline.social_auth.social_user', 148 | 'social.pipeline.user.get_username', 149 | 'social.pipeline.mail.mail_validation', 150 | 'social.pipeline.user.create_user', 151 | 'example.app.pipeline.set_password', 152 | 'social.pipeline.social_auth.associate_user', 153 | 'social.pipeline.social_auth.load_extra_data', 154 | 'social.pipeline.user.user_details' 155 | ) 156 | 157 | SOCIAL_AUTH_DISCONNECT_PIPELINE = ( 158 | 'example.app.pipeline.password_check', 159 | 'social.pipeline.disconnect.allowed_to_disconnect', 160 | 'social.pipeline.disconnect.get_entries', 161 | 'social.pipeline.disconnect.revoke_tokens', 162 | 'social.pipeline.disconnect.disconnect' 163 | ) 164 | 165 | 166 | try: 167 | from example.local_settings import * 168 | except ImportError: 169 | pass 170 | --------------------------------------------------------------------------------