├── .gitignore ├── COPYRIGHT.django-twitter-oauth ├── ChangeLog ├── LICENSE ├── LICENSE.django-openid-auth ├── Makefile ├── README.rst ├── django-social-auth.spec ├── doc ├── Makefile ├── backends │ ├── amazon.rst │ ├── angel.rst │ ├── appsfuel.rst │ ├── behance.rst │ ├── bitbucket.rst │ ├── browserid.rst │ ├── disqus.rst │ ├── douban.rst │ ├── dropbox.rst │ ├── evernote.rst │ ├── exacttarget.rst │ ├── facebook.rst │ ├── flickr.rst │ ├── github.rst │ ├── google.rst │ ├── index.rst │ ├── instagram.rst │ ├── jawbone.rst │ ├── linkedin.rst │ ├── live.rst │ ├── mailru.rst │ ├── mendeley.rst │ ├── mixcloud.rst │ ├── oauth.rst │ ├── odnoklassnikiru.rst │ ├── openid.rst │ ├── rdio.rst │ ├── readability.rst │ ├── reddit.rst │ ├── shopify.rst │ ├── skyrock.rst │ ├── soundcloud.rst │ ├── stackoveflow.rst │ ├── steam.rst │ ├── stocktwits.rst │ ├── stripe.rst │ ├── taobao.rst │ ├── tripit.rst │ ├── tumblr.rst │ ├── twilio.rst │ ├── twitter.rst │ ├── vk.rst │ ├── weibo.rst │ └── yahoo.rst ├── bugs.rst ├── changelog.rst ├── conf.py ├── configuration.rst ├── contributions.rst ├── copyrights.rst ├── demo.rst ├── deprecated.rst ├── images │ ├── facebook_1.jpeg │ └── facebook_2.jpeg ├── index.rst ├── installing.rst ├── intro.rst ├── miscellaneous.rst ├── pipeline.rst ├── testing.rst ├── testing_tools.rst ├── tokens.rst └── use_cases.rst ├── example ├── app │ ├── __init__.py │ ├── facebook.py │ ├── models.py │ ├── odnoklassniki.py │ ├── pipeline.py │ ├── views.py │ └── vkontakte.py ├── example │ ├── __init__.py │ ├── local_settings.py.template │ ├── middleware.py │ ├── robots.txt │ ├── settings.py │ ├── templates │ │ ├── base.html │ │ ├── close_popup.html │ │ ├── done.html │ │ ├── error.html │ │ ├── facebook.html │ │ ├── form.html │ │ ├── form2.html │ │ ├── home.html │ │ ├── odnoklassniki.html │ │ ├── odnoklassniki_info.html │ │ ├── vkontakte.html │ │ └── vkontakte_app.html │ ├── urls.py │ └── wsgi.py └── manage.py ├── requirements.txt ├── setup.py └── social_auth ├── __init__.py ├── admin.py ├── backends ├── __init__.py ├── amazon.py ├── aol.py ├── browserid.py ├── contrib │ ├── __init__.py │ ├── angel.py │ ├── appsfuel.py │ ├── behance.py │ ├── belgiumeid.py │ ├── bitbucket.py │ ├── dailymotion.py │ ├── disqus.py │ ├── douban.py │ ├── dropbox.py │ ├── evernote.py │ ├── exacttarget.py │ ├── fedora.py │ ├── fitbit.py │ ├── flickr.py │ ├── foursquare.py │ ├── gae.py │ ├── github.py │ ├── instagram.py │ ├── jawbone.py │ ├── linkedin.py │ ├── live.py │ ├── livejournal.py │ ├── mailru.py │ ├── mendeley.py │ ├── mixcloud.py │ ├── odnoklassniki.py │ ├── orkut.py │ ├── rdio.py │ ├── readability.py │ ├── shopify.py │ ├── skyrock.py │ ├── soundcloud.py │ ├── stackoverflow.py │ ├── stocktwits.py │ ├── taobao.py │ ├── trello.py │ ├── tripit.py │ ├── tumblr.py │ ├── twilio.py │ ├── vk.py │ ├── vkontakte.py │ ├── weibo.py │ ├── xing.py │ ├── yahoo.py │ ├── yammer.py │ ├── yammer_staging.py │ └── yandex.py ├── facebook.py ├── google.py ├── pipeline │ ├── __init__.py │ ├── associate.py │ ├── misc.py │ ├── sauth.py │ └── user.py ├── reddit.py ├── steam.py ├── stripe.py ├── twitter.py └── yahoo.py ├── context_processors.py ├── exceptions.py ├── fields.py ├── locale ├── it │ └── LC_MESSAGES │ │ ├── django.mo │ │ └── django.po └── pt_BR │ └── LC_MESSAGES │ ├── django.mo │ └── django.po ├── middleware.py ├── migrations ├── 0001_initial.py ├── 0002_auto__add_unique_nonce_timestamp_salt_server_url__add_unique_associati.py └── __init__.py ├── models.py ├── strategy.py ├── urls.py ├── utils.py └── views.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .*.sw[po] 3 | test*.db 4 | local_settings.py 5 | build/ 6 | dist/ 7 | django_social_auth.egg-info/ 8 | social_auth.egg-info/ 9 | env/ 10 | doc/_build 11 | example/templates/script*.html 12 | contrib/tests/test_settings.py 13 | *.ipr 14 | *.iws 15 | *.DS_Store 16 | Django-social-auth.iml 17 | tags 18 | Vagrantfile 19 | .vagrant 20 | .*project 21 | .settings 22 | .coverage 23 | settings.js 24 | fabfile.py 25 | -------------------------------------------------------------------------------- /COPYRIGHT.django-twitter-oauth: -------------------------------------------------------------------------------- 1 | Original Copyright goes to Henrik Lied (henriklied) 2 | Code borrowed from https://github.com/henriklied/django-twitter-oauth 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2012, Matías Aguirre 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of this project nor the names of its contributors may be 15 | used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /LICENSE.django-openid-auth: -------------------------------------------------------------------------------- 1 | django-openid-auth - OpenID integration for django.contrib.auth 2 | Copyright (C) 2007 Simon Willison 3 | Copyright (C) 2008-2010 Canonical Ltd. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 20 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 26 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | doc-tar: 2 | tar -czvf doc-example.tar.gz example/ doc/ 3 | 4 | rpm: doc-tar 5 | rpmbuild --define "_topdir %(pwd)" \ 6 | --define "_builddir /tmp" \ 7 | --define "_rpmdir %{_topdir}" \ 8 | --define "_srcrpmdir %{_topdir}" \ 9 | --define "_specdir %{_topdir}" \ 10 | --define "_sourcedir %{_topdir}" \ 11 | -ba django-social-auth.spec 12 | 13 | mv noarch/*.rpm . 14 | 15 | test: 16 | rpmlint -i *.rpm *.spec 17 | 18 | clean: 19 | rm -rf noarch/ BUILDROOT/ 20 | rm -f doc-example.tar.gz 21 | 22 | distclean: clean 23 | rm -f *.rpm 24 | 25 | help: 26 | @echo "Usage: make " 27 | @echo " " 28 | @echo " doc-tar - create tarball with docs and example for RPM " 29 | @echo " rpm - create rpm package " 30 | @echo " test - test all packages/spec files with rpmlint " 31 | @echo " clean - clean files used to build " 32 | @echo " distclean - execute clean and remove all output files " 33 | @echo " help - show this help and exit " 34 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | **NOTE: THIS LIBRARY IS DEPRECATED IN FAVOR OF** `python-social-auth`_. **RIGHT NOW 2 | THIS LIBRARY DEPENDS DIRECTLY ON** `python-social-auth`_ **AND SHOULD BE CONSIDERED 3 | AS A MIGRATION STEP** 4 | 5 | Django Social Auth 6 | ================== 7 | 8 | Django Social Auth is an easy way to setup social authentication/authorization 9 | mechanism for Django projects. 10 | 11 | Crafted using base code from django-twitter-oauth_ and django-openid-auth_, 12 | it implements a common interface to define new authentication providers from 13 | third parties. 14 | 15 | You can view this app's documentation on `Read the Docs`_ too. 16 | 17 | 18 | .. contents:: Table of Contents 19 | 20 | 21 | Features 22 | -------- 23 | 24 | This application provides user registration and login using social site 25 | credentials. Some features are: 26 | 27 | - Registration and login with social sites using the following providers 28 | at the moment: 29 | 30 | * `Google OpenID`_ 31 | * `Google OAuth`_ 32 | * `Google OAuth2`_ 33 | * `Yahoo OpenID`_ 34 | * OpenId_ like myOpenID_ 35 | * `Twitter OAuth`_ 36 | * `Facebook OAuth`_ 37 | 38 | Some contributions added support for: 39 | 40 | * `DISQUS OAuth`_ 41 | * `LiveJournal OpenID`_ 42 | * `Orkut OAuth`_ 43 | * `Linkedin OAuth`_ 44 | * `Foursquare OAuth2`_ 45 | * `GitHub OAuth`_ 46 | * `Dropbox OAuth`_ 47 | * `Flickr OAuth`_ 48 | * `Vkontakte OAuth`_ 49 | * `MSN Live Connect OAuth2`_ 50 | * `Skyrock OAuth`_ 51 | * `Yahoo OAuth`_ 52 | * `Evernote OAuth`_ 53 | * `Mail.ru OAuth`_ 54 | * `Odnoklassniki OAuth`_ 55 | * `Mixcloud OAuth2`_ 56 | * `BitBucket OAuth`_ 57 | * `Douban OAuth`_ 58 | * `Fitbit OAuth`_ 59 | * `Instagram OAuth2`_ 60 | * `Twilio`_ 61 | * `Trello OAuth`_ 62 | * `Weibo OAuth2`_ 63 | * `Yandex OpenId`_ 64 | * `Shopify OAuth2`_ 65 | * `StockTwits OAuth2`_ 66 | * `Stackoverflow OAuth2`_ 67 | * `Fedora OpenID`_ 68 | * `Exacttarget HubExchange`_ 69 | * `Appsfuel OAuth2`_ 70 | 71 | - Basic user data population and signaling to allows custom fields values 72 | from providers' responses 73 | 74 | - Multiple social account associations to a single user 75 | 76 | - Custom User model override if needed (`auth.User`_ by default) 77 | 78 | - Extensible pipeline to handle authentication/association mechanism 79 | 80 | 81 | Demo 82 | ---- 83 | 84 | There's a demo at http://social.matiasaguirre.net/. 85 | Note: It lacks some backends' support at the moment. 86 | 87 | 88 | Contact 89 | ------- 90 | 91 | Join the `django-social-auth discussion list`_ and bring any questions or suggestions 92 | that would improve this application. 93 | 94 | Also join the IRC channel ``#django-social-auth`` on Freenode server. 95 | 96 | 97 | Documentation 98 | ------------- 99 | 100 | Extensive documentation at `Read the Docs`_. 101 | 102 | 103 | Dependencies 104 | ------------ 105 | 106 | Dependencies that **must** be met to use the application: 107 | 108 | - OpenId_ support depends on python-openid_ 109 | 110 | - OAuth_ support depends on python-oauth2_ 111 | 112 | - Several backends demands application registration on their corresponding 113 | sites 114 | 115 | 116 | Installation 117 | ------------ 118 | 119 | From pypi_:: 120 | 121 | $ pip install django-social-auth 122 | 123 | or:: 124 | 125 | $ easy_install django-social-auth 126 | 127 | or clone from github_:: 128 | 129 | $ git clone git://github.com/omab/django-social-auth.git 130 | 131 | and add social_auth to PYTHONPATH:: 132 | 133 | $ export PYTHONPATH=$PYTHONPATH:$(pwd)/django-social-auth/ 134 | 135 | or:: 136 | 137 | $ cd django-social-auth 138 | $ sudo python setup.py install 139 | 140 | 141 | 142 | Support 143 | --------------------- 144 | 145 | If you're having problems with using the project, use the support forum at CodersClan. 146 | 147 | .. image:: http://www.codersclan.net/graphics/getSupport_github4.png 148 | :width: 100px 149 | :height: 100px 150 | :scale: 10 151 | :target: http://codersclan.net/forum/index.php?repo_id=7 152 | 153 | 154 | 155 | Copyrights and Licence 156 | ---------------------- 157 | 158 | ``django-social-auth`` is protected by BSD licence. 159 | 160 | Some bits were derived from others' work and copyrighted by: 161 | 162 | - django-twitter-oauth:: 163 | 164 | Original Copyright goes to Henrik Lied (henriklied) 165 | Code borrowed from https://github.com/henriklied/django-twitter-oauth 166 | 167 | - django-openid-auth:: 168 | 169 | django-openid-auth - OpenID integration for django.contrib.auth 170 | Copyright (C) 2007 Simon Willison 171 | Copyright (C) 2008-2010 Canonical Ltd. 172 | 173 | 174 | .. _django-twitter-oauth: https://github.com/henriklied/django-twitter-oauth 175 | .. _django-openid-auth: https://launchpad.net/django-openid-auth 176 | .. _Read the Docs: http://django-social-auth.readthedocs.org/ 177 | .. _Google OpenID: https://developers.google.com/accounts/docs/OpenID 178 | .. _Google OAuth: https://developers.google.com/accounts/docs/OAuth 179 | .. _Google OAuth2: https://developers.google.com/accounts/docs/OAuth2 180 | .. _Yahoo OpenID: http://openid.yahoo.com/ 181 | .. _OpenId: http://openid.net/ 182 | .. _myOpenID: https://www.myopenid.com/ 183 | .. _Twitter OAuth: http://dev.twitter.com/pages/oauth_faq 184 | .. _Facebook OAuth: http://developers.facebook.com/docs/authentication/ 185 | .. _DISQUS OAuth: http://disqus.com/api/docs/auth/ 186 | .. _LiveJournal OpenID: http://www.livejournal.com/support/faqbrowse.bml?faqid=283 187 | .. _Orkut OAuth: http://code.google.com/apis/orkut/docs/rest/developers_guide_protocol.html#Authenticating 188 | .. _Linkedin OAuth: https://www.linkedin.com/secure/developer 189 | .. _Foursquare OAuth2: https://developer.foursquare.com/docs/oauth.html 190 | .. _GitHub OAuth: http://developer.github.com/v3/oauth/ 191 | .. _Dropbox OAuth: https://www.dropbox.com/developers_beta/reference/api 192 | .. _Flickr OAuth: http://www.flickr.com/services/api/ 193 | .. _Vkontakte OAuth: http://vk.com/developers.php?oid=-1&p=%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%BE%D0%B2 194 | .. _MSN Live Connect OAuth2: http://msdn.microsoft.com/en-us/library/live/hh243647.aspx 195 | .. _Skyrock OAuth: http://www.skyrock.com/developer/ 196 | .. _Yahoo OAuth: http://developer.yahoo.com/oauth/guide/oauth-auth-flow.html 197 | .. _Evernote OAuth: http://dev.evernote.com/documentation/cloud/chapters/Authentication.php 198 | .. _Mail.ru OAuth: http://api.mail.ru/docs/guides/oauth/ 199 | .. _Odnoklassniki OAuth: http://dev.odnoklassniki.ru/wiki/display/ok/The+OAuth+2.0+Protocol 200 | .. _Mixcloud OAuth2: http://www.mixcloud.com/developers/documentation/#authorization 201 | .. _BitBucket OAuth: https://confluence.atlassian.com/display/BITBUCKET/OAuth+on+Bitbucket 202 | .. _Douban OAuth: http://www.douban.com/service/apidoc/auth 203 | .. _Fitbit OAuth: https://wiki.fitbit.com/display/API/OAuth+Authentication+in+the+Fitbit+API 204 | .. _Instagram OAuth2: http://instagram.com/developer/authentication/ 205 | .. _Twilio: https://www.twilio.com/user/account/connect/apps 206 | .. _Trello OAuth: https://trello.com/docs/gettingstarted/index.html#getting-an-application-key 207 | .. _Weibo OAuth2: http://open.weibo.com/wiki/Oauth2 208 | .. _Yandex OpenId: http://openid.yandex.ru/ 209 | .. _Shopify OAuth2: http://api.shopify.com/authentication.html 210 | .. _StockTwits OAuth2: http://stocktwits.com/developers/docs/authentication 211 | .. _auth.User: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py#L186 212 | .. _python-openid: http://pypi.python.org/pypi/python-openid/ 213 | .. _python-oauth2: https://github.com/simplegeo/python-oauth2 214 | .. _OAuth: http://oauth.net/ 215 | .. _pypi: http://pypi.python.org/pypi/django-social-auth/ 216 | .. _github: https://github.com/omab/django-social-auth 217 | .. _django-social-auth discussion list: https://groups.google.com/forum/?fromgroups#!forum/django-social-auth 218 | .. _Stackoverflow OAuth2: http://api.stackexchange.com/ 219 | .. _Fedora OpenID: https://fedoraproject.org/wiki/OpenID 220 | .. _Exacttarget HubExchange: http://code.exacttarget.com/ 221 | .. _Appsfuel OAuth2: http://docs.appsfuel.com/api_reference#api_reference 222 | .. _python-social-auth: https://github.com/omab/python-social-auth 223 | -------------------------------------------------------------------------------- /django-social-auth.spec: -------------------------------------------------------------------------------- 1 | %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} 2 | %{!?pyver: %define pyver %(%{__python} -c "import sys ; print sys.version[:3]")} 3 | 4 | Name: %(%{__python} setup.py --name) 5 | Version: %(%{__python} setup.py --version) 6 | Release: 1%{?dist} 7 | Summary: %(%{__python} setup.py --description) 8 | 9 | Group: Development/Libraries 10 | License: BSD 11 | URL: %(%{__python} setup.py --url) 12 | Source0: http://pypi.python.org/packages/source/d/django-social-auth/%{name}-%{version}.tar.gz 13 | Source1: LICENSE 14 | Source2: LICENSE.django-openid-auth 15 | Source3: COPYRIGHT.django-twitter-oauth 16 | Source4: doc-example.tar.gz 17 | 18 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) 19 | 20 | BuildArch: noarch 21 | BuildRequires: python-devel 22 | 23 | # Needs python-sphinx-1.0.7 which is not available in RHEL-6 24 | %if 0%{?rhel} > 6 || 0%{?fedora} > 12 25 | BuildRequires: python-sphinx 26 | %endif 27 | 28 | # NB: update this when updating requirements.txt 29 | Requires: Django >= 1.2.5 30 | Requires: python-oauth2 >= 1.5.167 31 | Requires: python-openid >= 2.2 32 | 33 | 34 | %description 35 | Django Social Auth is an easy to setup social authentication/authorization 36 | mechanism for Django projects. 37 | 38 | This application provides user registration and login using social sites 39 | supporting OpenID, OAuth and OAuth2 such as Google, Yahoo, Twitter, Facebook, 40 | LiveJournal, Orkut, LinkedIn, Foursquare, GitHub, DropBox, Flickr, Fedora. 41 | 42 | %package docs 43 | Summary: Documentation for %{name} 44 | Group: Documentation 45 | Requires: %{name} = %{version}-%{release} 46 | 47 | %description docs 48 | This package contains the documentation and example for %{name} 49 | 50 | %prep 51 | %setup -q 52 | 53 | # extract doc/ and example/ 54 | tar -xzf %{SOURCE4} 55 | 56 | %build 57 | %{__python} setup.py build 58 | 59 | # build the docs if we have 60 | %if 0%{?rhel} > 6 || 0%{?fedora} >= 12 61 | make html -C doc/ 62 | %endif 63 | 64 | %install 65 | rm -rf $RPM_BUILD_ROOT 66 | %{__python} setup.py install --skip-build --root $RPM_BUILD_ROOT 67 | 68 | mkdir -p %{buildroot}/%{_docdir}/%{name}-%{version} 69 | install -m 0644 %{SOURCE1} %{buildroot}/%{_docdir}/%{name}-%{version} 70 | install -m 0644 %{SOURCE2} %{buildroot}/%{_docdir}/%{name}-%{version} 71 | install -m 0644 %{SOURCE3} %{buildroot}/%{_docdir}/%{name}-%{version} 72 | 73 | 74 | # If it's rhel6+ or any Fedora over 12 build docs 75 | %if 0%{?rhel} > 6 || 0%{?fedora} >= 12 76 | # build documentation 77 | (cd docs && make html) 78 | %else 79 | cp -r doc/ %{buildroot}/%{_docdir}/%{name}-%{version} 80 | %endif 81 | 82 | cp -r example/ %{buildroot}/%{_docdir}/%{name}-%{version} 83 | 84 | %clean 85 | rm -rf $RPM_BUILD_ROOT 86 | 87 | 88 | %files 89 | %defattr(-,root,root,-) 90 | %doc %{_docdir}/%{name}-%{version}/LICENSE* 91 | %doc %{_docdir}/%{name}-%{version}/COPYRIGHT* 92 | %{python_sitelib}/social_auth/* 93 | 94 | # Leaving these since people may want to rebuild on lower dists 95 | %if 0%{?fedora} >= 9 || 0%{?rhel} >= 6 96 | %{python_sitelib}/*.egg-info 97 | %endif 98 | 99 | %files docs 100 | %defattr(-,root,root,-) 101 | %doc %{_docdir}/%{name}-%{version}/doc 102 | %doc %{_docdir}/%{name}-%{version}/example 103 | 104 | 105 | %changelog 106 | 107 | * Fri Jan 20 2011 Alexander Todorov - 0.6.1-1 108 | - initial package 109 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 14 | 15 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest 16 | 17 | help: 18 | @echo "Please use \`make ' where is one of" 19 | @echo " html to make standalone HTML files" 20 | @echo " dirhtml to make HTML files named index.html in directories" 21 | @echo " singlehtml to make a single large HTML file" 22 | @echo " pickle to make pickle files" 23 | @echo " json to make JSON files" 24 | @echo " htmlhelp to make HTML files and a HTML help project" 25 | @echo " qthelp to make HTML files and a qthelp project" 26 | @echo " devhelp to make HTML files and a Devhelp project" 27 | @echo " epub to make an epub" 28 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 29 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 30 | @echo " text to make text files" 31 | @echo " man to make manual pages" 32 | @echo " changes to make an overview of all changed/added/deprecated items" 33 | @echo " linkcheck to check all external links for integrity" 34 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 35 | 36 | clean: 37 | -rm -rf $(BUILDDIR)/* 38 | 39 | html: 40 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 41 | @echo 42 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 43 | 44 | dirhtml: 45 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 46 | @echo 47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 48 | 49 | singlehtml: 50 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 51 | @echo 52 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 53 | 54 | pickle: 55 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 56 | @echo 57 | @echo "Build finished; now you can process the pickle files." 58 | 59 | json: 60 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 61 | @echo 62 | @echo "Build finished; now you can process the JSON files." 63 | 64 | htmlhelp: 65 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 66 | @echo 67 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 68 | ".hhp project file in $(BUILDDIR)/htmlhelp." 69 | 70 | qthelp: 71 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 72 | @echo 73 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 74 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 75 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/DjangoSocialAuth.qhcp" 76 | @echo "To view the help file:" 77 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/DjangoSocialAuth.qhc" 78 | 79 | devhelp: 80 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 81 | @echo 82 | @echo "Build finished." 83 | @echo "To view the help file:" 84 | @echo "# mkdir -p $$HOME/.local/share/devhelp/DjangoSocialAuth" 85 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/DjangoSocialAuth" 86 | @echo "# devhelp" 87 | 88 | epub: 89 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 90 | @echo 91 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 92 | 93 | latex: 94 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 95 | @echo 96 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 97 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 98 | "(use \`make latexpdf' here to do that automatically)." 99 | 100 | latexpdf: 101 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 102 | @echo "Running LaTeX files through pdflatex..." 103 | make -C $(BUILDDIR)/latex all-pdf 104 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 105 | 106 | text: 107 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 108 | @echo 109 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 110 | 111 | man: 112 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 113 | @echo 114 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 115 | 116 | changes: 117 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 118 | @echo 119 | @echo "The overview file is in $(BUILDDIR)/changes." 120 | 121 | linkcheck: 122 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 123 | @echo 124 | @echo "Link check complete; look for any errors in the above output " \ 125 | "or in $(BUILDDIR)/linkcheck/output.txt." 126 | 127 | doctest: 128 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 129 | @echo "Testing of doctests in the sources finished, look at the " \ 130 | "results in $(BUILDDIR)/doctest/output.txt." 131 | -------------------------------------------------------------------------------- /doc/backends/amazon.rst: -------------------------------------------------------------------------------- 1 | ====== 2 | Amazon 3 | ====== 4 | 5 | Amazon implemented OAuth2 protocol for their authentication mechanism. To 6 | enable ``django-social-auth`` support follow this steps: 7 | 8 | 1. Go to `Amazon App Console`_ and create an application. 9 | 10 | 11 | 2. Fill App Id and Secret in your project settings:: 12 | 13 | AMAZON_APP_ID = '...' 14 | AMAZON_API_SECRET = '...' 15 | 16 | 3. Enable the backend:: 17 | 18 | AUTHENTICATION_BACKENDS = ( 19 | ... 20 | 'social_auth.backends.amazon.AmazonBackend', 21 | ... 22 | ) 23 | 24 | 25 | Notes 26 | ----- 27 | 28 | At the moment (May 29, 2013), Amazon API doesn't work properly, for example 29 | users are being redirected to URLs like:: 30 | 31 | https://www.amazon.com:80/ap/signin?... 32 | 33 | Which are invalid (``https`` over port 80?). The process works OK when removing 34 | the ``:80`` from those URLs, but this renders the service very unusable at the 35 | moment. 36 | 37 | User data returned by Amazon doesn't follow the documented format:: 38 | { 39 | Request-Id: "02GGTU7CWMNFTV3KH3J6", 40 | Profile: { 41 | Name: "Foo Bar", 42 | CustomerId: "amzn1.account.ABCDE1234", 43 | PrimaryEmail: "foo@bar.com" 44 | } 45 | } 46 | 47 | Instead of:: 48 | { 49 | "user_id": "amzn1.account.ABCDE1234", 50 | "email": "foo@bar.com", 51 | "name": "Foo Bar" 52 | } 53 | 54 | Further documentation at `Website Developer Guide`_ and `Getting Started for Web`_. 55 | 56 | .. _Amazon App Console: http://login.amazon.com/manageApps 57 | .. _Website Developer Guide: https://images-na.ssl-images-amazon.com/images/G/01/lwa/dev/docs/website-developer-guide._TTH_.pdf 58 | .. _Getting Started for Web: http://login.amazon.com/website 59 | -------------------------------------------------------------------------------- /doc/backends/angel.rst: -------------------------------------------------------------------------------- 1 | Angel List 2 | ========= 3 | Angel uses OAuth v2 for Authentication 4 | 5 | - Register a new application at the `Angel List API`_, and 6 | 7 | - fill ``Client Id`` and ``Client Secret`` values in the settings:: 8 | 9 | ANGEL_CLIENT_ID = '' 10 | ANGEL_CLIENT_SECRET = '' 11 | 12 | - extra scopes can be defined by using:: 13 | 14 | ANGEL_AUTH_EXTRA_ARGUMENTS = {'scope': 'email message'} 15 | 16 | *Note:* 17 | Angel List does not currently support returning 'state' variable. 18 | 19 | .. _Angel List API: https://angel.co/api/oauth/faq 20 | -------------------------------------------------------------------------------- /doc/backends/appsfuel.rst: -------------------------------------------------------------------------------- 1 | Appsfuel 2 | ======== 3 | Appsfuel uses OAuth v2 for Authentication (`Official Docs`_) 4 | 5 | - Sign up at the `Appsfuel Developer Program`_ 6 | 7 | - Create and verify a new app 8 | 9 | - On the dashboard click on **Show API keys** 10 | 11 | - Fill ``Client Id`` and ``Client Secret`` values in the settings:: 12 | 13 | APPSFUEL_CLIENT_ID = '' 14 | APPSFUEL_CLIENT_SECRET = '' 15 | 16 | Appsfuel gives you the chance to integrate with **Live** or **Sandbox** env. 17 | 18 | Appsfuel Live 19 | ------------- 20 | 21 | - Add 'social_auth.backends.contrib.appsfuel.AppsfuelBackend' into your AUTHENTICATION_BACKENDS. 22 | 23 | - Then you can start using {% url 'socialauth_begin' 'appsfuel' %} in your templates 24 | 25 | Appsfuel Sandbox 26 | ---------------- 27 | 28 | - Add 'social_auth.backends.contrib.appsfuel.AppsfuelSandboxBackend' into your AUTHENTICATION_BACKENDS. 29 | 30 | - Then you can start using {% url 'socialauth_begin' 'appsfuel-sandbox' %} in your templates 31 | 32 | 33 | .. _Official Docs: http://docs.appsfuel.com/api_reference#api_integration 34 | .. _Appsfuel Developer Program: https://developer.appsfuel.com 35 | -------------------------------------------------------------------------------- /doc/backends/behance.rst: -------------------------------------------------------------------------------- 1 | Behance 2 | ======= 3 | Behance uses OAuth2 for its auth mechanism. 4 | 5 | - Register a new application at `Behance App Registration`_, set your 6 | application name, website and redirect URI. 7 | 8 | - Fill ``Client Id`` and ``Client Secret`` values in the settings:: 9 | 10 | BEHANCE_CLIENT_ID = '' 11 | BEHANCE_CLIENT_SECRET = '' 12 | 13 | - Also it's possible to define extra permissions with:: 14 | 15 | BEHANCE_EXTENDED_PERMISSIONS = [...] 16 | 17 | Check available permissions at `Possible Scopes`_. Also check the rest of their 18 | doc at `Behance Developer Documentation`_. 19 | 20 | .. _Behance App Registration: http://www.behance.net/dev/register 21 | .. _Possible Scopes: http://www.behance.net/dev/authentication#scopes 22 | .. _Behance Developer Documentation: http://www.behance.net/dev 23 | -------------------------------------------------------------------------------- /doc/backends/bitbucket.rst: -------------------------------------------------------------------------------- 1 | Bitbucket 2 | ^^^^^^^^^ 3 | Bitbucket works similar to Twitter (OAuth). 4 | 5 | - Register a new application by emailing ``support@bitbucket.org`` with an 6 | application name and a bit of a description, 7 | 8 | - Fill ``Consumer Key`` and ``Consumer Secret`` values in the settings:: 9 | 10 | BITBUCKET_CONSUMER_KEY = '' 11 | BITBUCKET_CONSUMER_SECRET = '' 12 | -------------------------------------------------------------------------------- /doc/backends/browserid.rst: -------------------------------------------------------------------------------- 1 | --------- 2 | BrowserID 3 | --------- 4 | Support for BrowserId_ is possible by posting the ``assertion`` code to 5 | ``/complete/browserid/`` URL. 6 | 7 | The setup doesn't need any setting, just the usual BrowserId_ javascript 8 | include in your document and the needed mechanism to trigger the POST to 9 | `django-social-auth`_. 10 | 11 | Include a similar snippet in your page to make BrowserId_ work:: 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | BrowserID 20 |
21 | 22 | 24 | 44 | 45 | .. _django-social-auth: https://github.com/omab/django-social-auth 46 | .. _BrowserId: https://browserid.org 47 | -------------------------------------------------------------------------------- /doc/backends/disqus.rst: -------------------------------------------------------------------------------- 1 | DISQUS 2 | ========= 3 | DISQUS uses OAuth v2 for Authentication 4 | 5 | - Register a new application at the `DISQUS API`_, and 6 | 7 | - fill ``Client Id`` and ``Client Secret`` values in the settings:: 8 | 9 | DISQUS_CLIENT_ID = '' 10 | DISQUS_CLIENT_SECRET = '' 11 | 12 | - extra scopes can be defined by using:: 13 | 14 | DISQUS_AUTH_EXTRA_ARGUMENTS = {'scope': 'likes comments relationships'} 15 | 16 | *Note:* 17 | DISQUS only allows one callback url so you'll have to change your urls.py to 18 | accomodate both ``/complete`` and ``/associate`` routes, for example by having 19 | a single ``/associate`` url which takes a ``?complete=true`` parameter for the 20 | cases when you want to complete rather than associate. 21 | 22 | .. _DISQUS AUTH API: http://disqus.com/api/docs/auth/ 23 | .. _DISQUS API: http://disqus.com/api/applications/ 24 | -------------------------------------------------------------------------------- /doc/backends/douban.rst: -------------------------------------------------------------------------------- 1 | Douban 2 | ====== 3 | 4 | Douban OAuth 5 | ------------ 6 | Douban OAuth works similar to Twitter. 7 | 8 | Douban offers per application keys named ``Consumer Key`` and ``Consumer 9 | Secret``. To enable Douban OAuth these two keys are needed. Further 10 | documentation at `Douban Services & API`_: 11 | 12 | - Register a new application at `DOUBAN API KEY`_, 13 | 14 | - Mark the **web application** checkbox. 15 | 16 | - Fill **Consumer Key** and **Consumer Secret** values in settings:: 17 | 18 | DOUBAN_CONSUMER_KEY 19 | DOUBAN_CONSUMER_SECRET 20 | 21 | - Add ``'social_auth.backends.contrib.douban.DoubanBackend'`` 22 | into your ``AUTHENTICATION_BACKENDS``. 23 | 24 | - Then you can start using ``{% url 'socialauth_begin' 'douban' %}`` in your 25 | templates 26 | 27 | 28 | Douban OAuth2 29 | ------------- 30 | Recently Douban launched their OAuth2 support and the new developer site, you 31 | can find documentation at `Douban Developers`_: 32 | 33 | - Register a new application at `Create A Douban App`_, 34 | 35 | - Mark the **web application** checkbox. 36 | 37 | - Fill **Consumer Key** and **Consumer Secret** values in settings:: 38 | 39 | DOUBAN2_CONSUMER_KEY 40 | DOUBAN2_CONSUMER_SECRET 41 | 42 | - Add ``'social_auth.backends.contrib.douban.DoubanBackend2'`` 43 | into your ``AUTHENTICATION_BACKENDS``. 44 | 45 | - Then you can start using ``{% url 'socialauth_begin' 'douban2' %}`` in your 46 | templates. 47 | 48 | .. _Douban Services & API: http://www.douban.com/service/ 49 | .. _Douban API KEY: http://www.douban.com/service/apikey/apply 50 | .. _Douban Developers : http://developers.douban.com/ 51 | .. _Create A Douban App : http://developers.douban.com/apikey/apply 52 | -------------------------------------------------------------------------------- /doc/backends/dropbox.rst: -------------------------------------------------------------------------------- 1 | Dropbox 2 | ^^^^^^^ 3 | 4 | Dropbox uses OAuth v1.0 for authentication. 5 | 6 | - Register a new application at `Dropbox Developers`_, and 7 | 8 | - fill ``App Key`` and ``App Secret`` values in the settings:: 9 | 10 | DROPBOX_APP_ID = '' 11 | DROPBOX_API_SECRET = '' 12 | 13 | .. _Dropbox Developers: https://www.dropbox.com/developers/apps 14 | -------------------------------------------------------------------------------- /doc/backends/evernote.rst: -------------------------------------------------------------------------------- 1 | Evernote OAuth 2 | ============== 3 | 4 | Evernote OAuth 1.0 workflow. 5 | 6 | - Register a new application at `Evernote API Key form`_. 7 | 8 | - Fill ``Consumer Key`` and ``Consumer Secret`` values in the settings:: 9 | 10 | EVERNOTE_CONSUMER_KEY = '' 11 | EVERNOTE_CONSUMER_SECRET = '' 12 | 13 | - To test in the sandbox add to settings:: 14 | 15 | EVERNOTE_DEBUG = True 16 | 17 | .. _Evernote API Key form: http://dev.evernote.com/support/api_key.php 18 | -------------------------------------------------------------------------------- /doc/backends/exacttarget.rst: -------------------------------------------------------------------------------- 1 | ExactTarget 2 | ^^^^^^^^^^^ 3 | 4 | ExactTarget uses a JWT for authentication. 5 | 6 | To use this backend, you must install the package ``pyjwt`` (`Github`_) 7 | 8 | - Register a new application at `code.exacttarget.com`_, and 9 | 10 | - Set the Logon URL to http://[your domain]/social/complete/exacttarget/ 11 | 12 | - fill ``Application Signature`` values in your django settings:: 13 | 14 | EXACTTARGET_APP_SIGNATURE = '' 15 | 16 | .. _code.exacttarget.com: http://code.exacttarget.com 17 | .. _Github: https://github.com/progrium/pyjwt/ 18 | -------------------------------------------------------------------------------- /doc/backends/facebook.rst: -------------------------------------------------------------------------------- 1 | ======== 2 | Facebook 3 | ======== 4 | 5 | Facebook works similar to Twitter but it's simpler to setup and redirect URL 6 | is passed as a parameter when issuing an authorization. Further documentation 7 | can be found at `Facebook development resources`_: 8 | 9 | The steps below will get django-social-auth connected to your app running on *localhost*. 10 | 11 | #. Register a new application at `Facebook App Creation`_, follow along with the screenshots to setup your app: 12 | 13 | #. .. image:: ../images/facebook_1.jpeg 14 | 15 | #. .. image:: ../images/facebook_2.jpeg 16 | 17 | #. Back to your django settings.py file, fill in the ``App ID`` and ``App Secret`` values from the blue box in step #3 :: 18 | 19 | FACEBOOK_APP_ID='App ID here' 20 | FACEBOOK_API_SECRET='App Secret here' 21 | 22 | #. Make sure that you have the Facebook backend added to AUTHENTICATION_BACKENDS :: 23 | 24 | AUTHENTICATION_BACKENDS = ( 25 | 'social_auth.backends.facebook.FacebookBackend', 26 | ) 27 | 28 | #. You should now have Facebook enabled on localhost. 29 | 30 | 31 | Facebook Extended Permissions 32 | ============================= 33 | 34 | This is an optional step and only needed if you require extra information from Facebook such as email addresses, etc. 35 | 36 | - In django settings.py, define ``FACEBOOK_EXTENDED_PERMISSIONS`` to get extra permissions from facebook. For example, Facebook doesn't return user email by default, this setting is needed if email is required:: 37 | 38 | FACEBOOK_EXTENDED_PERMISSIONS = ['email'] 39 | 40 | - Define ``FACEBOOK_PROFILE_EXTRA_PARAMS`` to pass extra parameters to 41 | https://graph.facebook.com/me when gathering the user profile data, like:: 42 | 43 | FACEBOOK_PROFILE_EXTRA_PARAMS = {'locale': 'ru_RU'} 44 | 45 | Facebook Canvas 46 | =============== 47 | 48 | If you need to perform authentication from Facebook Canvas application: 49 | - Create your canvas application at http://developers.facebook.com/apps 50 | - In Facebook application settings specify your canvas URL 51 | ``mysite.com/fb`` (current default) 52 | - Setup your Django Social Auth settings like you usually do for Facebook 53 | authentication (FACEBOOK_APP_ID etc) 54 | - Launch manage.py via sudo ``./manage.py runserver mysite.com:80`` for 55 | browser to be able to load it when Facebook calls canvas URL 56 | - Open your Facebook page via http://apps.facebook.com/app_namespace or 57 | better via http://www.facebook.com/pages/user-name/user-id?sk=app_app-id 58 | - After that you will see this page in a right way and will able to connect 59 | to application and login automatically after connection 60 | 61 | More info on the topic at `Facebook Canvas Application Authentication`_. 62 | 63 | .. _dnsmasq: http://www.thekelleys.org.uk/dnsmasq/doc.html 64 | .. _Facebook development resources: http://developers.facebook.com/docs/authentication/ 65 | .. _Facebook App Creation: http://developers.facebook.com/setup/ 66 | .. _Facebook Canvas Application Authentication: http://www.ikrvss.ru/2011/09/22/django-social-auth-and-facebook-canvas-applications/ 67 | -------------------------------------------------------------------------------- /doc/backends/flickr.rst: -------------------------------------------------------------------------------- 1 | Flickr 2 | ^^^^^^ 3 | Flickr uses OAuth v1.0 for authentication. 4 | 5 | - Register a new application at the `Flickr App Garden`_, and 6 | 7 | - fill ``Key`` and ``Secret`` values in the settings:: 8 | 9 | FLICKR_APP_ID = '' 10 | FLICKR_API_SECRET = '' 11 | 12 | - Flickr might show a messages saying "Oops! Flickr doesn't recognise the 13 | permission set.", if encountered with this error, just define this setting:: 14 | 15 | FLICKR_AUTH_EXTRA_ARGUMENTS = {'perms':'read'} 16 | 17 | 18 | .. _Flickr App Garden: http://www.flickr.com/services/apps/create/ 19 | -------------------------------------------------------------------------------- /doc/backends/github.rst: -------------------------------------------------------------------------------- 1 | GitHub 2 | ====== 3 | Github works similar to Facebook (OAuth). 4 | 5 | - Register a new application at `GitHub Developers`_, set your site domain as 6 | the callback URL or it might cause some troubles when associating accounts, 7 | 8 | - Fill ``App Id`` and ``App Secret`` values in the settings:: 9 | 10 | GITHUB_APP_ID = '' 11 | GITHUB_API_SECRET = '' 12 | 13 | - Also it's possible to define extra permissions with:: 14 | 15 | GITHUB_EXTENDED_PERMISSIONS = [...] 16 | 17 | - Optional ``GitHub Organization``, which if set will allow you to constrain 18 | authentication to a given GitHub organization:: 19 | 20 | GITHUB_ORGANIZATION = '' 21 | 22 | .. _GitHub Developers: https://github.com/settings/applications/new 23 | -------------------------------------------------------------------------------- /doc/backends/google.rst: -------------------------------------------------------------------------------- 1 | Google 2 | ====== 3 | 4 | This section describes how to setup the different services provided by 5 | Google. 6 | 7 | Google OAuth 8 | ------------ 9 | 10 | Google provides ``Consumer Key`` and ``Consumer Secret`` keys to registered 11 | applications, but also allows unregistered application to use their authorization 12 | system with, but beware that this method will display a security banner to the 13 | user telling that the application is not trusted. 14 | 15 | Check `Google OAuth`_ and make your choice. 16 | 17 | - fill ``Consumer Key`` and ``Consumer Secret`` values:: 18 | 19 | GOOGLE_CONSUMER_KEY 20 | GOOGLE_CONSUMER_SECRET 21 | 22 | anonymous values will be used if not configured as described in their 23 | `OAuth reference`_ 24 | 25 | - configure the display name to be used in the *grant permissions* dialog 26 | that Google will display to users in:: 27 | 28 | GOOGLE_DISPLAY_NAME = '' 29 | 30 | shows 'Social Auth' by default, but that might not suite your application. 31 | 32 | - setup any needed extra scope in:: 33 | 34 | GOOGLE_OAUTH_EXTRA_SCOPE = [...] 35 | 36 | - Supply a list of Google Apps account domain strings to be checked. The default (empty list) allows all domains. If a list is provided and a user attempts to sign in with a Google account that is not in the list, then a ValueError will be raised and the user will be redirected to your login error page:: 37 | 38 | GOOGLE_WHITE_LISTED_DOMAINS = ['mygoogleappsdomain.com'] 39 | 40 | - Supply a list of Google Apps or Gmail email strings to be checked:: 41 | 42 | GOOGLE_WHITE_LISTED_EMAILS = ['me@mygoogleappsdomain.com', 'you@gmail.com'] 43 | 44 | Check which applications can be included in their `Google Data Protocol Directory`_ 45 | 46 | 47 | Google OAuth2 48 | ------------- 49 | 50 | Recently Google launched OAuth2 support following the definition at `OAuth2 draft`. 51 | It works in a similar way to plain OAuth mechanism, but developers **must** register 52 | an application and apply for a set of keys. Check `Google OAuth2`_ document for details. 53 | 54 | **Note**: 55 | This support is experimental as Google implementation may change and OAuth2 is still 56 | a draft. 57 | 58 | To enable OAuth2 support: 59 | 60 | - fill ``Client ID`` and ``Client Secret`` settings, these values can be obtained 61 | easily as described on `OAuth2 Registering`_ doc:: 62 | 63 | GOOGLE_OAUTH2_CLIENT_ID = '' 64 | GOOGLE_OAUTH2_CLIENT_SECRET = '' 65 | 66 | previous name ``GOOGLE_OAUTH2_CLIENT_KEY`` is supported for backward 67 | compatibility. 68 | 69 | - scopes are shared between OAuth mechanisms:: 70 | 71 | GOOGLE_OAUTH_EXTRA_SCOPE = [...] 72 | 73 | - optional support for static and unique Google Profile ID identifiers instead of 74 | using the e-mail address for account association can be enabled with:: 75 | 76 | GOOGLE_OAUTH2_USE_UNIQUE_USER_ID = True 77 | 78 | Check which applications can be included in their `Google Data Protocol Directory`_ 79 | 80 | 81 | Google OAut2 Offline Mode 82 | ------------------------- 83 | 84 | This setting is needed in order to get a refresh token from while using Google 85 | OAut2 backend:: 86 | 87 | GOOGLE_OAUTH2_AUTH_EXTRA_ARGUMENTS = {'access_type': 'offline'} 88 | 89 | This will add a ``refresh_token`` entry in the ``UserSocialAuth.extra_data`` 90 | attribute of the related association. With this token it's possible to refresh 91 | the ``access_token`` at any time by calling:: 92 | 93 | user_social_auth.refresh_token() 94 | 95 | You can get the ``user_social_auth`` instance with a code similar to this:: 96 | 97 | user = User.objects.get(pk=...) 98 | user_social_auth = user.social_auth.get(provider="google-oauth2") 99 | 100 | 101 | Google OpenID 102 | ------------- 103 | 104 | Configurable settings: 105 | 106 | - Supply a list of Google Apps account domain strings to be checked:: 107 | 108 | GOOGLE_WHITE_LISTED_DOMAINS = ['mygoogleappsdomain.com'] 109 | 110 | - Supply a list of Google Apps or Gmail email strings to be checked:: 111 | 112 | GOOGLE_WHITE_LISTED_EMAILS = ['me@mygoogleappsdomain.com', 'you@gmail.com'] 113 | 114 | 115 | Orkut 116 | ----- 117 | 118 | Orkut offers per application keys named ``Consumer Key`` and ``Consumer Secret``. 119 | To enable Orkut these two keys are needed. 120 | 121 | Check `Google support`_ and `Orkut API`_ for details on getting 122 | your consumer_key and consumer_secret keys. 123 | 124 | - fill ``Consumer Key`` and ``Consumer Secret`` values:: 125 | 126 | ORKUT_CONSUMER_KEY 127 | ORKUT_CONSUMER_SECRET 128 | 129 | - add any needed extra data to:: 130 | 131 | ORKUT_EXTRA_DATA = '' 132 | 133 | - configure extra scopes in:: 134 | 135 | ORKUT_EXTRA_SCOPES = [...] 136 | 137 | 138 | .. _Google support: http://www.google.com/support/a/bin/answer.py?hl=en&answer=162105 139 | .. _Orkut API: http://code.google.com/apis/orkut/docs/rest/developers_guide_protocol.html#Authenticating 140 | .. _Google OpenID: http://code.google.com/apis/accounts/docs/OpenID.html 141 | .. _Google OAuth: http://code.google.com/apis/accounts/docs/OAuth.html 142 | .. _Google OAuth2: http://code.google.com/apis/accounts/docs/OAuth2.html 143 | .. _OAuth2 Registering: http://code.google.com/apis/accounts/docs/OAuth2.html#Registering 144 | .. _Google Data Protocol Directory: http://code.google.com/apis/gdata/docs/directory.html 145 | .. _OAuth2 draft: http://tools.ietf.org/html/draft-ietf-oauth-v2-10 146 | .. _OAuth reference: http://code.google.com/apis/accounts/docs/OAuth_ref.html#SigningOAuth 147 | .. _Orkut OAuth: http://code.google.com/apis/orkut/docs/rest/developers_guide_protocol.html#Authenticating 148 | -------------------------------------------------------------------------------- /doc/backends/index.rst: -------------------------------------------------------------------------------- 1 | Django Social Auth backends system 2 | ================================== 3 | 4 | Contents: 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | oauth 10 | openid 11 | 12 | amazon 13 | angel 14 | appsfuel 15 | behance 16 | bitbucket 17 | browserid 18 | disqus 19 | douban 20 | dropbox 21 | evernote 22 | exacttarget 23 | facebook 24 | flickr 25 | github 26 | google 27 | instagram 28 | linkedin 29 | live 30 | mailru 31 | mixcloud 32 | odnoklassnikiru 33 | rdio 34 | readability 35 | reddit 36 | shopify 37 | skyrock 38 | soundcloud 39 | stackoverflow 40 | steam 41 | stocktwits 42 | stripe 43 | tripit 44 | tumblr 45 | twilio 46 | twitter 47 | vk 48 | weibo 49 | yahoo 50 | -------------------------------------------------------------------------------- /doc/backends/instagram.rst: -------------------------------------------------------------------------------- 1 | Instagram 2 | ========= 3 | Instagram uses OAuth v2 for Authentication 4 | 5 | - Register a new application at the `Instagram API`_, and 6 | 7 | - fill ``Client Id`` and ``Client Secret`` values in the settings:: 8 | 9 | INSTAGRAM_CLIENT_ID = '' 10 | INSTAGRAM_CLIENT_SECRET = '' 11 | 12 | - extra scopes can be defined by using:: 13 | 14 | INSTAGRAM_AUTH_EXTRA_ARGUMENTS = {'scope': 'likes comments relationships'} 15 | 16 | *Note:* 17 | Instagram only allows one callback url so you'll have to change your urls.py to 18 | accomodate both ``/complete`` and ``/associate`` routes, for example by having 19 | a single ``/associate`` url which takes a ``?complete=true`` parameter for the 20 | cases when you want to complete rather than associate. 21 | 22 | .. _Instagram API: http://instagr.am/developer/ 23 | -------------------------------------------------------------------------------- /doc/backends/jawbone.rst: -------------------------------------------------------------------------------- 1 | Jawbone 2 | ========= 3 | Jawbone uses OAuth v2 for Authentication 4 | 5 | - Register a new application at the `Jawbone UP Platform`_, and 6 | 7 | - fill ``Client Id`` and ``Client Secret`` values in the settings:: 8 | 9 | JAWBONE_CLIENT_ID = '' 10 | JAWBONE_CLIENT_SECRET = '' 11 | 12 | - extra scopes can be defined by using:: 13 | 14 | JAWBONE_EXTENDED_PERMISSIONS = ['basic_read', 'mood_read', 'mood_write'] 15 | 16 | .. _Jawbone UP Platform: https://jawbone.com/up/platform/ 17 | -------------------------------------------------------------------------------- /doc/backends/linkedin.rst: -------------------------------------------------------------------------------- 1 | LinkedIn 2 | ======== 3 | 4 | LinkedIn setup is similar to any other OAuth service. To request extra fields 5 | using `LinkedIn fields selectors`_ just define this setting:: 6 | 7 | LINKEDIN_EXTRA_FIELD_SELECTORS = [...] 8 | 9 | with the needed fields selectors, also define LINKEDIN_EXTRA_DATA properly as 10 | described in `OAuth `_, that way the values will be stored in 11 | ``UserSocialAuth.extra_data`` field. 12 | 13 | By default ``id``, ``first-name`` and ``last-name`` are requested and stored. 14 | 15 | If you want to request a user's email address, you'll need specify that your 16 | application needs access to the email address using the ``r_emailaddress`` 17 | scope parameter. 18 | 19 | Note that there are two backends available for linkedin, linkedin and 20 | linkedin-oauth2. You will need to include the appropriate backends to make each 21 | work. 22 | 23 | Also note that until they figure out a migration plan, they 24 | require new API keys from the LinkedIn API (Issued after August 6th, 2012). 25 | 26 | LinkedIn emulates the scope parameter of OAuth2 to specify user privileges. 27 | Check here for `scope possibilities`_ if you need more than just the basic 28 | profile. 29 | 30 | These are declared as a list by defining this setting:: 31 | 32 | LINKEDIN_SCOPE = ['r_basicprofile', ...] 33 | 34 | For example, to request a user's email, headline, and industry from the 35 | Linkedin API and store the information in ``UserSocialAuth.extra_data``, you 36 | would add these settings:: 37 | 38 | # Add email to requested authorizations. 39 | LINKEDIN_SCOPE = ['r_basicprofile', 'r_emailaddress', ...] 40 | # Add the fields so they will be requested from linkedin. 41 | LINKEDIN_EXTRA_FIELD_SELECTORS = ['email-address', 'headline', 'industry'] 42 | # Arrange to add the fields to UserSocialAuth.extra_data 43 | LINKEDIN_EXTRA_DATA = [('id', 'id'), 44 | ('first-name', 'first_name'), 45 | ('last-name', 'last_name'), 46 | ('email-address', 'email_address'), 47 | ('headline', 'headline'), 48 | ('industry', 'industry')] 49 | 50 | If you are using linkedin-oauth2 as a backend, note that the configuration will 51 | use LINKEDIN_OAUTH2_EXTRA_DATA. In addition, you should look into the name of 52 | the fields that are returned to make sure they will match when constructing 53 | extra_data. Currently (May 2013), the configuration should be as follows: 54 | 55 | LINKEDIN_OAUTH2_EXTRA_DATA = [('id', 'id'), 56 | ('firstName', 'first_name'), 57 | ('lastName', 'last_name'),...] 58 | 59 | .. _LinkedIn fields selectors: http://developer.linkedin.com/docs/DOC-1014 60 | .. _scope possibilities: https://developer.linkedin.com/documents/authentication#granting 61 | 62 | Linkedin allow members to do their profiles in multiple languages. 63 | By default linkedin's profile is retrieved with the user's primary language. 64 | This behavior can be changed with ``LINKEDIN_FORCE_PROFILE_LANGUAGE``, you can 65 | set it as ``True``, ``'django'`` or as the locale you want. 66 | ``True`` will use ``django.utils.translation.get_language``. If no language 67 | has been found or setted as ``False``, it will get member's profile on his primary language. 68 | 69 | e.g:: 70 | 71 | # The default, no needs to be setted, it will get the member's primary language 72 | LINKEDIN_FORCE_PROFILE_LANGUAGE = False 73 | 74 | # Use django get_language 75 | LINKEDIN_FORCE_PROFILE_LANGUAGE = 'django' 76 | # The same as above 77 | LINKEDIN_FORCE_PROFILE_LANGUAGE = True 78 | 79 | # Force linkedin to get member's pt-br profile 80 | LINKEDIN_FORCE_PROFILE_LANGUAGE = 'pt-BR' 81 | -------------------------------------------------------------------------------- /doc/backends/live.rst: -------------------------------------------------------------------------------- 1 | MSN Live Connect 2 | ================ 3 | OAuth2 based Live Connect workflow, notice that it isn't OAuth WRAP. 4 | 5 | - Register a new application at `Live Connect Developer Center`_, set your site domain as 6 | redirect domain, 7 | 8 | - Fill ``Client Id`` and ``Client Secret`` values in the settings:: 9 | 10 | LIVE_CLIENT_ID = '' 11 | LIVE_CLIENT_SECRET = '' 12 | 13 | - Also it's possible to define extra permissions with:: 14 | 15 | LIVE_EXTENDED_PERMISSIONS = [...] 16 | 17 | Defaults are "wl.basic" and "wl.emails". Latter one is necessary to retrieve user email. 18 | 19 | .. _Live Connect Developer Center: https://manage.dev.live.com/Applications/Index 20 | -------------------------------------------------------------------------------- /doc/backends/mailru.rst: -------------------------------------------------------------------------------- 1 | Mail.ru OAuth 2 | ============= 3 | 4 | Mail.ru uses OAuth2 workflow, to use it fill in settings:: 5 | 6 | MAILRU_OAUTH2_CLIENT_KEY = '' 7 | MAILRU_OAUTH2_APP_KEY = '' 8 | MAILRU_OAUTH2_CLIENT_SECRET = '' 9 | -------------------------------------------------------------------------------- /doc/backends/mendeley.rst: -------------------------------------------------------------------------------- 1 | Mendeley 2 | ========= 3 | Mendeley uses OAuth v2 for Authentication 4 | 5 | - Register a new application at the `Mendeley API`_, and 6 | 7 | - fill ``Consumer Key`` and ``Consumer Secret`` values in the settings:: 8 | 9 | MENDELEY_CONSUMER_KEY = '' 10 | MENDELEY_CONSUMER_SECRET = '' 11 | 12 | .. _Mendeley API: http://apidocs.mendeley.com/ 13 | -------------------------------------------------------------------------------- /doc/backends/mixcloud.rst: -------------------------------------------------------------------------------- 1 | Mixcloud OAuth2 2 | =============== 3 | 4 | The `Mixcloud API`_ offers support for authorization. 5 | To enable OAuth2 support: 6 | 7 | - Register a new application at `Mixcloud Developers`_ 8 | 9 | - Add Mixcloud backend to ``AUTHENTICATION_BACKENDS`` in settings:: 10 | 11 | AUTHENTICATION_BACKENDS = ( 12 | ... 13 | 'social_auth.backends.contrib.mixcloud.MixcloudBackend', 14 | ) 15 | 16 | - Fill ``Client Id`` and ``Client Secret`` values in the settings:: 17 | 18 | MIXCLOUD_CLIENT_ID = '' 19 | MIXCLOUD_CLIENT_SECRET = '' 20 | 21 | - Similar to the other OAuth backends you can define:: 22 | 23 | MIXCLOUD_EXTRA_DATA = [('username', 'username'), ('name', 'name'), ('pictures', 'pictures'), ('url', 'url')] 24 | 25 | as a list of tuples ``(response name, alias)`` to store user profile data on the UserSocialAuth model. 26 | 27 | 28 | .. _Mixcloud API: http://www.mixcloud.com/developers/documentation 29 | .. _Mixcloud Developers: http://www.mixcloud.com/developers 30 | -------------------------------------------------------------------------------- /doc/backends/oauth.rst: -------------------------------------------------------------------------------- 1 | OAuth 2 | ===== 3 | 4 | OAuth_ communication demands a set of keys exchange to validate the client 5 | authenticity prior to user approbation. Twitter, Facebook and Orkut 6 | facilitates these keys by application registration, Google works the same, 7 | but provides the option for unregistered applications. 8 | 9 | Check next sections for details. 10 | 11 | OAuth_ backends also can store extra data in ``UserSocialAuth.extra_data`` 12 | field by defining a set of values names to retrieve from service response. 13 | 14 | Settings is per backend and its name is dynamically checked using uppercase 15 | backend name as prefix:: 16 | 17 | _EXTRA_DATA 18 | 19 | For example, a subset of the data GitHub's provider returns is:: 20 | 21 | { 22 | 'avatar_url': 'https://secure.gravatar.com/avatar/[...]', 23 | 'created_at': '2009-02-11T02:18:24Z', 24 | 'email': 'john@example.com', 25 | 'id': 53537, 26 | 'login': 'github_user' 27 | 'name': 'Johnny Codemore', 28 | [...] 29 | } 30 | 31 | To add the avatar and login items to ``UserSocialAuth.extra_data``, you would 32 | define the following in ``settings.py``:: 33 | 34 | GITHUB_EXTRA_DATA = [ 35 | ('avatar_url', 'avatar'), 36 | ('login', 'login'), 37 | ] 38 | 39 | Settings must be a list of tuples mapping value name in response and value's 40 | alias used in ``UserSocialAuth.extra_data``. The alias is used to normalize 41 | data access across multiple backends. In the example above, GitHub sends 42 | back a URL for the avatar in the field ``avatar_url``. Alternatively, another 43 | backend can send it as ``avatar``, or ``gravatar``. By using a single name, 44 | ``avatar``, within ``UserSocialAuth.extra_data`` your application can more 45 | easily use this information. 46 | 47 | A third value (boolean) is supported, its purpose is to signal if the value 48 | should be discarded if it evaluates to ``False``, this is to avoid replacing 49 | old (needed) values when they don't form part of current response. If not 50 | present, then this check is avoided and the value will replace any data. 51 | 52 | 53 | .. _OAuth: http://oauth.net/ 54 | -------------------------------------------------------------------------------- /doc/backends/odnoklassnikiru.rst: -------------------------------------------------------------------------------- 1 | Odnoklassniki.ru 2 | ================ 3 | 4 | There are two options with Odnoklassniki: either you use OAuth2 workflow to 5 | authenticate odnoklassniki users at external site, or you authenticate users 6 | within your IFrame application. 7 | 8 | OAuth 9 | ----- 10 | If you use OAuth2 workflow, you need to: 11 | 12 | - register a new application with `OAuth registration form`_ 13 | - fill out some settings:: 14 | 15 | ODNOKLASSNIKI_OAUTH2_CLIENT_KEY = '' 16 | ODNOKLASSNIKI_OAUTH2_APP_KEY = '' 17 | ODNOKLASSNIKI_OAUTH2_CLIENT_SECRET = '' 18 | 19 | - add ``'social_auth.backends.contrib.odnoklassniki.OdnoklassnikiBackend'`` 20 | into your ``AUTHENTICATION_BACKENDS``. 21 | 22 | IFrame applications 23 | ------------------- 24 | 25 | If you want to authenticate users in your IFrame application, 26 | 27 | - read `Rules for application developers`_ 28 | - fill out `Developers registration form`_ 29 | - get your personal sandbox 30 | - fill out some settings:: 31 | 32 | ODNOKLASSNIKI_APP_ID = '' 33 | ODNOKLASSNIKI_APP_PUBLIC_KEY = '' 34 | ODNOKLASSNIKI_APP_SECRET = '' 35 | 36 | - add ``'social_auth.backends.contrib.odnoklassniki.OdnoklassnikiAppBackend'`` 37 | into your ``AUTHENTICATION_BACKENDS`` 38 | - sign a public offer and do some bureaucracy 39 | 40 | You may also use some options: 41 | 42 | - ``ODNOKLASSNIKI_APP_EXTRA_USER_DATA_LIST`` (defaults to empty tuple), for the 43 | list of available fields see `Documentation on user.getInfo`_ 44 | - ``ODNOKLASSNIKI_SANDBOX_DEV_USERNAME`` and 45 | ``ODNOKLASSNIKI_SANDBOX_DEV_PASSWORD`` are username and password of your 46 | sandbox. They are only used in IFrame app testing 47 | - ``ODNOKLASSNIKI_TEST_USERNAME`` and ``ODNOKLASSNIKI_TEST_PASSWORD`` should be 48 | username (or email) and password of real Odnoklassniki user. They are only 49 | used in OAuth testing. 50 | 51 | .. _OAuth registration form: http://dev.odnoklassniki.ru/wiki/pages/viewpage.action?pageId=13992188 52 | .. _Rules for application developers: http://dev.odnoklassniki.ru/wiki/display/ok/Odnoklassniki.ru+Third+Party+Platform 53 | .. _Developers registration form: http://dev.odnoklassniki.ru/wiki/pages/viewpage.action?pageId=5668937 54 | .. _Documentation on user.getInfo: http://dev.odnoklassniki.ru/wiki/display/ok/REST+API+-+users.getInfo 55 | -------------------------------------------------------------------------------- /doc/backends/openid.rst: -------------------------------------------------------------------------------- 1 | OpenId 2 | ====== 3 | 4 | OpenId_ support is simpler to implement than OAuth_. Google and Yahoo 5 | providers are supported by default, others are supported by POST method 6 | providing endpoint URL. 7 | 8 | OpenId_ backends can store extra data in ``UserSocialAuth.extra_data`` field 9 | by defining a set of values names to retrieve from any of the used schemas, 10 | AttributeExchange and SimpleRegistration. As their keywords differ we need 11 | two settings. 12 | 13 | Settings is per backend, so we have two possible values for each one. Name 14 | is dynamically checked using uppercase backend name as prefix:: 15 | 16 | _SREG_EXTRA_DATA 17 | _AX_EXTRA_DATA 18 | 19 | Example:: 20 | 21 | GOOGLE_SREG_EXTRA_DATA = [(..., ...)] 22 | GOOGLE_AX_EXTRA_DATA = [(..., ...)] 23 | 24 | Settings must be a list of tuples mapping value name in response and value 25 | alias used to store. A third value (boolean) is supported to, it's purpose is 26 | to signal if the value should be discarded if it evaluates to ``False``, this 27 | is to avoid replacing old (needed) values when they don't form part of current 28 | response. If not present, then this check is avoided and the value will replace 29 | any data. 30 | 31 | .. _OpenId: http://openid.net/ 32 | .. _OAuth: http://oauth.net/ 33 | -------------------------------------------------------------------------------- /doc/backends/rdio.rst: -------------------------------------------------------------------------------- 1 | Rdio 2 | ==== 3 | 4 | OAuth 1.0a 5 | ---------- 6 | 7 | To setup Rdio OAuth 1.0a, add the following to your settings page:: 8 | 9 | AUTHENTICATION_BACKENDS = ( 10 | ... 11 | 'social_auth.backends.contrib.rdio.RdioOAuth1Backend', 12 | ... 13 | ) 14 | 15 | RDIO_OAUTH1_KEY = os.environ['RDIO_OAUTH1_KEY'] 16 | RDIO_OAUTH1_SECRET = os.environ['RDIO_OAUTH1_SECRET'] 17 | 18 | 19 | OAuth 2.0 20 | --------- 21 | 22 | To setup Rdio OAuth 2.0, add the following to your settings page:: 23 | 24 | AUTHENTICATION_BACKENDS = ( 25 | ... 26 | 'social_auth.backends.contrib.rdio.RdioOAuth2Backend', 27 | ... 28 | ) 29 | 30 | RDIO_OAUTH2_KEY = os.environ['RDIO_OAUTH2_KEY'] 31 | RDIO_OAUTH2_SECRET = os.environ['RDIO_OAUTH2_SECRET'] 32 | RDIO2_PERMISSIONS = [] 33 | 34 | 35 | Extra Fields 36 | ------------ 37 | 38 | The following extra fields are automatically requested: 39 | 40 | - rdio_id 41 | - rdio_icon_url 42 | - rdio_profile_url 43 | - rdio_username 44 | - rdio_stream_region 45 | -------------------------------------------------------------------------------- /doc/backends/readability.rst: -------------------------------------------------------------------------------- 1 | Readability 2 | ======= 3 | 4 | Readability works similarly to Twitter, in that you'll need a ``Consumer Key`` 5 | and ``Consumer Secret``. These can be obtained in the ``Connections`` section 6 | of your ``Account`` page. 7 | 8 | - Fill the **Consumer Key** and **Consumer Secret** values in your settings: 9 | 10 | READABILITY_CONSUMER_KEY 11 | READABILITY_CONSUMER_SECRET 12 | 13 | That's it! By default you'll get back: 14 | 15 | username 16 | first_name 17 | last_name 18 | 19 | with EXTRA_DATA, you can get: 20 | 21 | date_joined 22 | kindle_email_address 23 | avatar_url 24 | email_into_address -------------------------------------------------------------------------------- /doc/backends/reddit.rst: -------------------------------------------------------------------------------- 1 | Reddit 2 | ====== 3 | 4 | Reddit implements `OAuth2 authentication workflow`_. To enable it, just follow: 5 | 6 | - Register an application at `Reddit Preferences Apps`_ 7 | 8 | - Fill the **Consumer Key** and **Consumer Secret** values in your settings:: 9 | 10 | REDDIT_APP_ID = '' 11 | REDDIT_API_SECRET = '' 12 | 13 | - By default the token is not permanent, it will last an hour. To get 14 | a refresh token just define:: 15 | 16 | REDDIT_AUTH_EXTRA_ARGUMENTS = {'duration': 'permanent'} 17 | 18 | This will store the ``refresh_token`` in ``UserSocialAuth.extra_data`` 19 | attribute, to refresh the access token just do:: 20 | 21 | from social_auth.backends.reddit import RedditAuth 22 | 23 | user = User.objects.get(pk=foo) 24 | social = user.social_auth.filter(provider='reddit')[0] 25 | new_token = RedditAuth.refresh_token(social.extra_data['refresh_token'], 26 | redirect_uri='http://localhost:8000/complete/reddit/') 27 | s.extra_data.update(new_token) 28 | s.save() 29 | 30 | Reddit requires ``redirect_uri`` when refreshing the token and it must be the 31 | same value used during the auth process. 32 | 33 | .. _Reddit Preferences Apps: https://ssl.reddit.com/prefs/apps/ 34 | .. _OAuth2 authentication workflow: https://github.com/reddit/reddit/wiki/OAuth2 35 | -------------------------------------------------------------------------------- /doc/backends/shopify.rst: -------------------------------------------------------------------------------- 1 | Shopify 2 | ^^^^^^^ 3 | 4 | Shopify uses OAuth 2 for authentication. 5 | 6 | To use this backend, you must install the package ``shopify`` (`Github`_) 7 | 8 | - Register a new application at `Shopify Partners`_, and 9 | 10 | - Set the Auth Type to OAuth2 in the application settings 11 | 12 | - Set the Application URL to http://[your domain]/social/login/shopify/ 13 | 14 | - fill ``API Key`` and ``Shared Secret`` values in your django settings:: 15 | 16 | SHOPIFY_APP_API_KEY = '' 17 | SHOPIFY_SHARED_SECRET = '' 18 | 19 | - fill the scope permissions that you require into the settings `Shopify API`_:: 20 | 21 | SHOPIFY_SCOPE = ["write_script_tags","read_orders","write_customers","read_products"] 22 | 23 | .. _Shopify Partners: http://www.shopify.com/partners 24 | .. _Shopify API: http://api.shopify.com/authentication.html#scopes 25 | .. _Github: https://github.com/Shopify/shopify_python_api 26 | -------------------------------------------------------------------------------- /doc/backends/skyrock.rst: -------------------------------------------------------------------------------- 1 | Skyrock 2 | ======= 3 | 4 | OAuth based Skyrock Connect. 5 | Skyrock offers per application keys named ``Consumer Key`` and ``Consumer Secret``. 6 | To enable Skyrock these two keys are needed. Further documentation at 7 | `Skyrock developer resources`_: 8 | 9 | - Register a new application at `Skyrock App Creation`_, 10 | 11 | - Your callback domain should match your application URL in your application configuration. 12 | 13 | - fill **Consumer Key** and **Consumer Secret** values:: 14 | 15 | SKYROCK_CONSUMER_KEY 16 | SKYROCK_CONSUMER_SECRET 17 | 18 | 19 | .. _Skyrock developer resources: http://www.skyrock.com/developer/ 20 | .. _Skyrock App Creation: https://wwwskyrock.com/developer/application 21 | -------------------------------------------------------------------------------- /doc/backends/soundcloud.rst: -------------------------------------------------------------------------------- 1 | SoundCloud 2 | ========== 3 | SoundCloud uses OAuth2 for its auth mechanism. 4 | 5 | - Register a new application at `SoundCloud App Registration`_, set your 6 | application name, website and redirect URI. 7 | 8 | - Fill ``Client Id`` and ``Client Secret`` values in the settings:: 9 | 10 | SOUNDCLOUD_CLIENT_ID = '' 11 | SOUNDCLOUD_CLIENT_SECRET = '' 12 | 13 | - Also it's possible to define extra permissions with:: 14 | 15 | SOUNDCLOUD_EXTENDED_PERMISSIONS = [...] 16 | 17 | Possible scope values are `*` or `non-expiring` according to their `/connect 18 | documentation`_. 19 | 20 | Check the rest of their doc at `SoundCloud Developer Documentation`_. 21 | 22 | .. _SoundCloud App Registration: http://soundcloud.com/you/apps/new 23 | .. _SoundCloud Developer Documentation: http://developers.soundcloud.com/docs 24 | .. _/connect documentation: http://developers.soundcloud.com/docs/api/reference#connect 25 | -------------------------------------------------------------------------------- /doc/backends/stackoveflow.rst: -------------------------------------------------------------------------------- 1 | Stackoverflow 2 | ====== 3 | Stackoverflow uses OAuth 2.0 4 | 5 | - "Register For An App Key" at the `Stack Exchange API` site. Set your OAuth 6 | domain and application website settings. 7 | 8 | - Add the ``Client Id``, ``Client Secret`` and ``Key`` values in settings:: 9 | 10 | STACKOVERFLOW_CLIENT_ID = '' 11 | STACKOVERFLOW_CLIENT_SECRET = '' 12 | STACKOVERFLOW_KEY = '' 13 | 14 | - You can ask for extra permissions with:: 15 | 16 | STACKOVERFLOW_EXTENDED_PERMISSIONS = [...] 17 | 18 | .. _Stack Exchange API: https://api.stackexchange.com/ 19 | -------------------------------------------------------------------------------- /doc/backends/steam.rst: -------------------------------------------------------------------------------- 1 | Steam OpenId 2 | ============ 3 | 4 | Steam OpenId works quite straightforward, but to retrieve some user data (known 5 | as ``player`` on Steam API) a Steam API Key is needed. 6 | 7 | Configurable settings: 8 | 9 | - Supply a Steam API Key from `Steam Dev`_:: 10 | 11 | STEAM_API_KEY = key 12 | 13 | .. _Steam Dev: http://steamcommunity.com/dev/apikey 14 | -------------------------------------------------------------------------------- /doc/backends/stocktwits.rst: -------------------------------------------------------------------------------- 1 | StockTwits 2 | ^^^^^^^^^^ 3 | 4 | StockTwits uses OAuth 2 for authentication. 5 | 6 | - Register a new application at https://stocktwits.com/developers/apps 7 | 8 | - Set the Website URL to http://[your domain]/ 9 | 10 | - fill ``Consumer Key`` and ``Consumer Secret`` values in your django settings:: 11 | 12 | STOCKTWITS_CONSUMER_KEY = '' 13 | STOCKTWITS_CONSUMER_SECRET = '' 14 | 15 | .. _StockTwits authentication docs: http://stocktwits.com/developers/docs/authentication 16 | .. _StockTwits API: http://stocktwits.com/developers/docs/api 17 | -------------------------------------------------------------------------------- /doc/backends/stripe.rst: -------------------------------------------------------------------------------- 1 | Stripe 2 | ====== 3 | 4 | Stripe uses OAuth2 for its authorization service. To setup Stripe backend: 5 | 6 | - Register a new application at `Stripe App Creation`_, and 7 | 8 | - Grab the ``client_id`` value in ``Applications`` tab and fill the ``App Id`` 9 | setting:: 10 | 11 | STRIPE_APP_ID = 'ca_...' 12 | 13 | - Grab the ``Test Secret Key`` in the ``API Keys`` tab and fille the ``App 14 | Secret`` setting:: 15 | 16 | STRIPE_APP_SECRET = '...' 17 | 18 | - Define ``STRIPE_SCOPE`` with the desired scope (options are ``read_only`` and 19 | ``read_write``):: 20 | 21 | STRIPE_SCOPE = ['read_only'] 22 | 23 | - Add the needed backend to ``AUTHENTICATION_BACKENDS``:: 24 | 25 | AUTHENTICATION_BACKENDS = ( 26 | ... 27 | 'social_auth.backends.stripe.StripeBackend', 28 | ... 29 | ) 30 | 31 | More info on Stripe OAuth2 at `Integrating OAuth`_. 32 | 33 | .. _Stripe App Creation: https://manage.stripe.com/#account/applications/settings 34 | .. _Integrating OAuth: https://stripe.com/docs/connect/oauth 35 | -------------------------------------------------------------------------------- /doc/backends/taobao.rst: -------------------------------------------------------------------------------- 1 | Taobao OAuth 2 | =========== 3 | 4 | Taobao OAuth 2.0 workflow. 5 | 6 | - Register a new application at Open Taobao_. 7 | 8 | - Fill ``Consumer Key`` and ``Consumer Secret`` values in the settings:: 9 | 10 | SOCIAL_AUTH_TAOBAO_KEY = '' 11 | SOCIAL_AUTH_TAOBAO_SECRET = '' 12 | 13 | By default ``token``is stored in 14 | extra_data field. 15 | 16 | .. _Taobao: http://open.taobao.com 17 | -------------------------------------------------------------------------------- /doc/backends/tripit.rst: -------------------------------------------------------------------------------- 1 | TripIt 2 | ======= 3 | 4 | TripIt offers per application keys named ``API Key`` and ``API Secret``. 5 | To enable TripIt these two keys are needed. Further documentation at 6 | `TripIt Developer Center`_: 7 | 8 | - Register a new application at `TripIt App Registration`_, 9 | 10 | - fill **API Key** and **API Secret** values:: 11 | 12 | TRIPIT_API_KEY 13 | TRIPIT_API_SECRET 14 | 15 | .. _TripIt Developer Center: https://www.tripit.com/developer 16 | .. _TripIt App Registration: https://www.tripit.com/developer/create 17 | -------------------------------------------------------------------------------- /doc/backends/tumblr.rst: -------------------------------------------------------------------------------- 1 | Tumblr 2 | ^^^^^^^^^^ 3 | 4 | Tumblr uses OAuth 1.0a for authentication. 5 | 6 | - Register a new application at http://www.tumblr.com/oauth/apps 7 | 8 | - Set the ``Default callback URL`` to http://[your domain]/ 9 | 10 | - fill ``OAuth Consumer Key`` and ``Secret Key`` values in your Django settings:: 11 | 12 | TUMBLR_CONSUMER_KEY = '' 13 | TUMBLR_CONSUMER_SECRET = '' 14 | 15 | .. _Tumblr API: http://www.tumblr.com/docs/en/api/v2 16 | -------------------------------------------------------------------------------- /doc/backends/twilio.rst: -------------------------------------------------------------------------------- 1 | twilio-backend 2 | ============== 3 | 4 | - Register a new application at `Twilio Connect Api`_ 5 | 6 | - Fill ``TWILIO_CONNECT_KEY`` and ``TWILIO_AUTH_TOKEN`` values in the 7 | settings:: 8 | 9 | TWILIO_CONNECT_KEY = '' 10 | TWILIO_AUTH_TOKEN = '' 11 | 12 | - Add desired authentication backends to Django's ``AUTHENTICATION_BACKENDS`` 13 | setting:: 14 | 15 | 'social_auth.backends.contrib.twilio.TwilioBackend', 16 | 17 | - Usage example:: 18 | 19 | Enter using Twilio 20 | 21 | 22 | .. _Twilio Connect API: https://www.twilio.com/user/account/connect/apps 23 | -------------------------------------------------------------------------------- /doc/backends/twitter.rst: -------------------------------------------------------------------------------- 1 | Twitter 2 | ======= 3 | 4 | Twitter offers per application keys named ``Consumer Key`` and ``Consumer Secret``. 5 | To enable Twitter these two keys are needed. Further documentation at 6 | `Twitter development resources`_: 7 | 8 | - Register a new application at `Twitter App Creation`_, 9 | 10 | - check the **Allow this application to be used to Sign in with Twitter** 11 | checkbox. If you don't check this box, Twitter will force your user to login 12 | every time. 13 | 14 | - fill **Consumer Key** and **Consumer Secret** values:: 15 | 16 | TWITTER_CONSUMER_KEY 17 | TWITTER_CONSUMER_SECRET 18 | 19 | - You need to specify an URL callback or the application will be marked as 20 | Client type instead of the Browser. Almost any dummy value will work if 21 | you plan some test. 22 | 23 | 24 | Twitter usually fails with a 401 error when trying to call the request-token 25 | URL, this is usually caused by server datetime errors (check miscellaneous 26 | section). Installing ``ntp`` and syncing the server date with some pool does 27 | the trick. 28 | 29 | .. _Twitter development resources: http://dev.twitter.com/pages/auth 30 | .. _Twitter App Creation: http://twitter.com/apps/new 31 | -------------------------------------------------------------------------------- /doc/backends/vk.rst: -------------------------------------------------------------------------------- 1 | VK.com 2 | ========= 3 | 4 | VK.com auth service supported. 5 | 6 | OAuth2 7 | ------ 8 | 9 | VKontakte uses OAuth2 for Authentication. 10 | 11 | - Register a new application at the `Vkontakte API`_, 12 | 13 | - fill ``Application Id`` and ``Application Secret`` values in the settings:: 14 | 15 | VK_APP_ID = '' 16 | VK_API_SECRET = '' 17 | 18 | - Add ``'social_auth.backends.contrib.vk.VKOAuth2Backend'`` into your ``AUTHENTICATION_BACKENDS``. 19 | 20 | - Then you can start using ``{% url 'socialauth_begin' 'vk-oauth' %}`` in your templates 21 | 22 | - Also it's possible to define extra permissions with:: 23 | 24 | VK_EXTRA_SCOPE = [...] 25 | 26 | See the `VK.com list of permissions`_. 27 | 28 | 29 | OpenAPI 30 | ------- 31 | 32 | You can also use VK.com's own OpenAPI to log in, but you need to provide 33 | HTML template with JavaScript code to authenticate. See ``vkontakte.html`` in 34 | templates folder for details. 35 | 36 | IFrame Applications 37 | ------------------- 38 | 39 | To support authentication for VKontakte applications: 40 | 41 | - Fill ``Application ID`` and ``Application Secret`` settings:: 42 | 43 | VKAPP_APP_ID = 44 | VKAPP_API_SECRET = 45 | 46 | - Create your IFrame application at vk.com. 47 | 48 | - In application settings specify your IFrame URL ``mysite.com/vk`` (current 49 | default). 50 | 51 | - You may need to also provide VKAPP_USER_MODE setting (0 by default) 52 | 53 | * ``VKAPP_USER_MODE`` values: 54 | 55 | - ``0``: there will be no check whether a user connected to your 56 | application or not 57 | - ``1``: ``Django-social-auth`` will check ``is_app_user`` parameter 58 | VKontakte sends when user opens application page one time 59 | - ``2``: (safest) ``Django-social-auth`` will check status of user 60 | interactively (useful when you have interactive authentication via AJAX) 61 | 62 | - To test, launch the server using ``sudo ./manage.py mysite.com:80`` for 63 | browser to be able to load it when VKontakte calls IFrame URL. 64 | 65 | - Open your VK.com application page via http://vk.com/app 66 | 67 | - Now you are able to connect to application and login automatically after 68 | connection when visiting application page. 69 | 70 | For more details see `authentication for VKontakte applications`_ 71 | 72 | .. _Vkontakte OAuth: http://vk.com/developers.php?oid=-1&p=%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%BE%D0%B2 73 | .. _VK.com list of permissions: http://vk.com/developers.php?oid=-1&p=%D0%9F%D1%80%D0%B0%D0%B2%D0%B0_%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%B0_%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9 74 | .. _Vkontakte API: http://vk.com/developers.php 75 | .. _authentication for VKontakte applications: http://www.ikrvss.ru/2011/11/08/django-social-auh-and-vkontakte-application/ 76 | -------------------------------------------------------------------------------- /doc/backends/weibo.rst: -------------------------------------------------------------------------------- 1 | Weibo OAuth 2 | =========== 3 | 4 | Weibo OAuth 2.0 workflow. 5 | 6 | - Register a new application at Weibo_. 7 | 8 | - Fill ``Consumer Key`` and ``Consumer Secret`` values in the settings:: 9 | 10 | WEIBO_CLIENT_KEY = '' 11 | WEIBO_CLIENT_SECRET = '' 12 | 13 | By default account id, profile_image_url, gender are stored in extra_data 14 | field, check OAuthBackend class for details on how to extend it. 15 | 16 | .. _Weibo: http://open.weibo.com 17 | -------------------------------------------------------------------------------- /doc/backends/yahoo.rst: -------------------------------------------------------------------------------- 1 | Yahoo OAuth 2 | =========== 3 | OAuth 1.0 workflow, useful if you are planning to use Yahoo's API. 4 | 5 | - Register a new application at `Yahoo Developer Center`_, set your app domain and configure scopes (they can't be overriden by application). 6 | 7 | - Fill ``Consumer Key`` and ``Consumer Secret`` values in the settings:: 8 | 9 | YAHOO_CONSUMER_KEY = '' 10 | YAHOO_CONSUMER_SECRET = '' 11 | 12 | .. _Yahoo Developer Center: https://developer.apps.yahoo.com/projects/ 13 | -------------------------------------------------------------------------------- /doc/bugs.rst: -------------------------------------------------------------------------------- 1 | Bugs 2 | ==== 3 | Maybe several, please report `issues in github`_ 4 | 5 | .. _issues in github: https://github.com/omab/django-social-auth/issues 6 | -------------------------------------------------------------------------------- /doc/changelog.rst: -------------------------------------------------------------------------------- 1 | ../ChangeLog -------------------------------------------------------------------------------- /doc/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Django Social Auth documentation build configuration file, created by 4 | # sphinx-quickstart on Sun Mar 20 23:07:14 2011. 5 | # 6 | # This file is execfile()d with the current directory set to its containing 7 | # dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | # If extensions (or modules to document with autodoc) are in another directory, 16 | # add these directories to sys.path here. If the directory is relative to the 17 | # documentation root, use os.path.abspath to make it absolute, like shown here. 18 | #sys.path.insert(0, os.path.abspath('.')) 19 | 20 | # -- General configuration ---------------------------------------------------- 21 | 22 | # If your documentation needs a minimal Sphinx version, state it here. 23 | #needs_sphinx = '1.0' 24 | 25 | # Add any Sphinx extension module names here, as strings. They can be 26 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 27 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 28 | 'sphinx.ext.todo', 'sphinx.ext.viewcode'] 29 | 30 | # Add any paths that contain templates here, relative to this directory. 31 | templates_path = ['_templates'] 32 | 33 | # The suffix of source filenames. 34 | source_suffix = '.rst' 35 | 36 | # The encoding of source files. 37 | #source_encoding = 'utf-8-sig' 38 | 39 | # The master toctree document. 40 | master_doc = 'index' 41 | 42 | # General information about the project. 43 | project = u'Django Social Auth' 44 | copyright = u'2011, Matías Aguirre' 45 | 46 | # The version info for the project you're documenting, acts as replacement for 47 | # |version| and |release|, also used in various other places throughout the 48 | # built documents. 49 | # 50 | # The short X.Y version. 51 | #version = '0.6.0' 52 | # The full version, including alpha/beta/rc tags. 53 | #release = '0.6.0' 54 | 55 | # The language for content autogenerated by Sphinx. Refer to documentation 56 | # for a list of supported languages. 57 | #language = None 58 | 59 | # There are two options for replacing |today|: either, you set today to some 60 | # non-false value, then it is used: 61 | #today = '' 62 | # Else, today_fmt is used as the format for a strftime call. 63 | #today_fmt = '%B %d, %Y' 64 | 65 | # List of patterns, relative to source directory, that match files and 66 | # directories to ignore when looking for source files. 67 | exclude_patterns = ['_build'] 68 | 69 | # The reST default role (used for this markup: `text`) to use for all 70 | # documents. 71 | #default_role = None 72 | 73 | # If true, '()' will be appended to :func: etc. cross-reference text. 74 | #add_function_parentheses = True 75 | 76 | # If true, the current module name will be prepended to all description 77 | # unit titles (such as .. function::). 78 | #add_module_names = True 79 | 80 | # If true, sectionauthor and moduleauthor directives will be shown in the 81 | # output. They are ignored by default. 82 | #show_authors = False 83 | 84 | # The name of the Pygments (syntax highlighting) style to use. 85 | pygments_style = 'sphinx' 86 | 87 | # A list of ignored prefixes for module index sorting. 88 | #modindex_common_prefix = [] 89 | 90 | 91 | # -- Options for HTML output -------------------------------------------------- 92 | 93 | # The theme to use for HTML and HTML Help pages. See the documentation for 94 | # a list of builtin themes. 95 | html_theme = 'default' 96 | 97 | # Theme options are theme-specific and customize the look and feel of a theme 98 | # further. For a list of options available for each theme, see the 99 | # documentation. 100 | #html_theme_options = {} 101 | 102 | # Add any paths that contain custom themes here, relative to this directory. 103 | #html_theme_path = [] 104 | 105 | # The name for this set of Sphinx documents. If None, it defaults to 106 | # " v documentation". 107 | #html_title = None 108 | 109 | # A shorter title for the navigation bar. Default is the same as html_title. 110 | #html_short_title = None 111 | 112 | # The name of an image file (relative to this directory) to place at the top 113 | # of the sidebar. 114 | #html_logo = None 115 | 116 | # The name of an image file (within the static path) to use as favicon of the 117 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 118 | # pixels large. 119 | #html_favicon = None 120 | 121 | # Add any paths that contain custom static files (such as style sheets) here, 122 | # relative to this directory. They are copied after the builtin static files, 123 | # so a file named "default.css" will overwrite the builtin "default.css". 124 | html_static_path = [] 125 | 126 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 127 | # using the given strftime format. 128 | #html_last_updated_fmt = '%b %d, %Y' 129 | 130 | # If true, SmartyPants will be used to convert quotes and dashes to 131 | # typographically correct entities. 132 | #html_use_smartypants = True 133 | 134 | # Custom sidebar templates, maps document names to template names. 135 | #html_sidebars = {} 136 | 137 | # Additional templates that should be rendered to pages, maps page names to 138 | # template names. 139 | #html_additional_pages = {} 140 | 141 | # If false, no module index is generated. 142 | #html_domain_indices = True 143 | 144 | # If false, no index is generated. 145 | #html_use_index = True 146 | 147 | # If true, the index is split into individual pages for each letter. 148 | #html_split_index = False 149 | 150 | # If true, links to the reST sources are added to the pages. 151 | #html_show_sourcelink = True 152 | 153 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 154 | #html_show_sphinx = True 155 | 156 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 157 | #html_show_copyright = True 158 | 159 | # If true, an OpenSearch description file will be output, and all pages will 160 | # contain a tag referring to it. The value of this option must be the 161 | # base URL from which the finished HTML is served. 162 | #html_use_opensearch = '' 163 | 164 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 165 | #html_file_suffix = None 166 | 167 | # Output file base name for HTML help builder. 168 | htmlhelp_basename = 'DjangoSocialAuthdoc' 169 | 170 | 171 | # -- Options for LaTeX output ------------------------------------------------- 172 | 173 | # The paper size ('letter' or 'a4'). 174 | #latex_paper_size = 'letter' 175 | 176 | # The font size ('10pt', '11pt' or '12pt'). 177 | #latex_font_size = '10pt' 178 | 179 | # Grouping the document tree into LaTeX files. List of tuples 180 | # (source start file, target name, title, author, documentclass 181 | # [howto/manual]). 182 | latex_documents = [ 183 | ('index', 'DjangoSocialAuth.tex', u'Django Social Auth Documentation', 184 | u'Matías Aguirre', 'manual'), 185 | ] 186 | 187 | # The name of an image file (relative to this directory) to place at the top of 188 | # the title page. 189 | #latex_logo = None 190 | 191 | # For "manual" documents, if this is true, then toplevel headings are parts, 192 | # not chapters. 193 | #latex_use_parts = False 194 | 195 | # If true, show page references after internal links. 196 | #latex_show_pagerefs = False 197 | 198 | # If true, show URL addresses after external links. 199 | #latex_show_urls = False 200 | 201 | # Additional stuff for the LaTeX preamble. 202 | #latex_preamble = '' 203 | 204 | # Documents to append as an appendix to all manuals. 205 | #latex_appendices = [] 206 | 207 | # If false, no module index is generated. 208 | #latex_domain_indices = True 209 | 210 | 211 | # -- Options for manual page output ------------------------------------------- 212 | 213 | # One entry per manual page. List of tuples 214 | # (source start file, name, description, authors, manual section). 215 | man_pages = [ 216 | ('index', 'djangosocialauth', u'Django Social Auth Documentation', 217 | [u'Matías Aguirre'], 1) 218 | ] 219 | 220 | 221 | # Example configuration for intersphinx: refer to the Python standard library. 222 | intersphinx_mapping = {'http://docs.python.org/': None} 223 | -------------------------------------------------------------------------------- /doc/contributions.rst: -------------------------------------------------------------------------------- 1 | Contributions 2 | ============= 3 | 4 | Attributions to whom deserves: 5 | 6 | caioariede_ (Caio Ariede): 7 | * Improvements and Orkut support 8 | 9 | krvss_ (Stas Kravets): 10 | * Initial setup.py configuration 11 | * LiveJournal support 12 | * Mail.ru, Odnoklassniki support 13 | * Yandex OpenID support 14 | * VKontakte OpenAPI support 15 | 16 | jezdez_ (Jannis Leidel): 17 | * Improvements and documentation update 18 | 19 | alfredo_ (Alfredo Ramirez) 20 | * Facebook and Doc improvements 21 | 22 | mattucf_ (Matt Brown) 23 | * Twitter and OAuth improvements 24 | 25 | Quard_ (Vadym Zakovinko) 26 | * LinkedIn support 27 | 28 | micrypt_ (Seyi Ogunyemi) 29 | * python-oauth2_ migration 30 | 31 | djm_ (Darian Moody) 32 | * Improvements 33 | 34 | bernardokyotoku_ (Bernardo Kyotoku) 35 | * Improvements 36 | 37 | maraujop_ (Miguel Araujo) 38 | * Improvements 39 | 40 | bedspax_ 41 | * Foursquare support 42 | 43 | revolunet_ (Julien Bouquillon) 44 | * GitHub support 45 | 46 | danielgtaylor_ (Daniel G. Taylor) 47 | * Dropbox support 48 | * Flickr support 49 | * Provider name context processor 50 | 51 | r4vi_ (Ravi Kotecha) 52 | * Instagram support 53 | 54 | andrusha_ (Andrew Korzhuev) 55 | * MSN Live Connect support 56 | * Yahoo OAuth 1.0 support 57 | 58 | niQo_ (Nicolas Quiénot) 59 | * Skyrock.com support 60 | 61 | hassek_ (Tomas Henriquez) 62 | * Evernote support 63 | 64 | fmoga_ (Florian Moga) 65 | * Mixcloud support 66 | 67 | estebistec_ (Steven Cummings) 68 | * Overrideable models feature 69 | 70 | hepochen_ 71 | * Weibo support 72 | 73 | northisup_ (Adam Hitchcock) 74 | * DISQUS support 75 | 76 | kjoconnor_ (Kevin O'Connor) 77 | * Readablity Support 78 | 79 | uruz_ (Alexey Boriskin) 80 | * Odnoklassniki.ru iframe applications support 81 | * VK.com backend improvements 82 | 83 | abompard_ (Aurélien Bompard) 84 | * Fedora OpenID support 85 | 86 | dhendo_ (David Henderson) 87 | * Shopify support 88 | * ExactTarget support 89 | 90 | gardaud_ (Guillaume Ardaud) 91 | * Option to revoke providers' tokens on disconnect. 92 | 93 | .. _caioariede: https://github.com/caioariede 94 | .. _krvss: https://github.com/krvss 95 | .. _jezdez: https://github.com/jezdez 96 | .. _alfredo: https://github.com/alfredo 97 | .. _mattucf: https://github.com/mattucf 98 | .. _Quard: https://github.com/Quard 99 | .. _micrypt: https://github.com/micrypt 100 | .. _djm: https://github.com/djm 101 | .. _bernardokyotoku: https://github.com/bernardokyotoku 102 | .. _andrusha: https://github.com/andrusha 103 | .. _maraujop: https://github.com/maraujop 104 | .. _bedspax: https://github.com/bedspax 105 | .. _python-oauth2: https://github.com/simplegeo/python-oauth2 106 | .. _niQo: https://github.com/niQo 107 | .. _hassek: https://github.com/hassek 108 | .. _fmoga: https://github.com/fmoga 109 | .. _revolunet: https://github.com/revolunet 110 | .. _r4vi: https://github.com/r4vi 111 | .. _danielgtaylor: https://github.com/danielgtaylor 112 | .. _estebistec: https://github.com/estebistec 113 | .. _hepochen: https://github.com/hepochen 114 | .. _northisup: https://github.com/northisup 115 | .. _kjoconnor: https://github.com/kjoconnor 116 | .. _uruz: https://github.com/uruz 117 | .. _abompard: https://github.com/abompard 118 | .. _dhendo: https://github.com/dhendo 119 | .. _gardaud: https://github.com/gardaud -------------------------------------------------------------------------------- /doc/copyrights.rst: -------------------------------------------------------------------------------- 1 | Copyrights and Licence 2 | ====================== 3 | 4 | ``django-social-auth`` is protected by BSD licence. 5 | 6 | Some bits were derived from others work and copyrighted by: 7 | 8 | - django-twitter-oauth:: 9 | 10 | Original Copyright goes to Henrik Lied (henriklied) 11 | Code borrowed from https://github.com/henriklied/django-twitter-oauth 12 | 13 | - django-openid-auth:: 14 | 15 | django-openid-auth - OpenID integration for django.contrib.auth 16 | Copyright (C) 2007 Simon Willison 17 | Copyright (C) 2008-2010 Canonical Ltd. 18 | -------------------------------------------------------------------------------- /doc/demo.rst: -------------------------------------------------------------------------------- 1 | Demo 2 | ==== 3 | There's a demo at http://social.matiasaguirre.net/. 4 | 5 | **Note**: It lacks some backends support at the moment. 6 | -------------------------------------------------------------------------------- /doc/deprecated.rst: -------------------------------------------------------------------------------- 1 | Deprecated bits 2 | =============== 3 | 4 | The following settings are deprecated in favor of pipeline functions. 5 | 6 | - These old settings aren't supported anymore, so override ``get_username`` 7 | pipeline entry with the desired behavior:: 8 | 9 | SOCIAL_AUTH_FORCE_RANDOM_USERNAME 10 | SOCIAL_AUTH_DEFAULT_USERNAME 11 | SOCIAL_AUTH_UUID_LENGTH 12 | SOCIAL_AUTH_USERNAME_FIXER 13 | SOCIAL_AUTH_ASSOCIATE_URL_NAME 14 | 15 | - User creation setting was removed, so remove the entry ``create_user`` 16 | from pipeline instead:: 17 | 18 | SOCIAL_AUTH_CREATE_USERS 19 | 20 | Also the signal ``socialauth_not_registered`` was removed. 21 | 22 | - Automatic data update is the default behavior, this old setting was removed:: 23 | 24 | SOCIAL_AUTH_CHANGE_SIGNAL_ONLY 25 | 26 | Override ``update_user_details`` if needed. 27 | 28 | - Extra data retrieval is default behavior, this setting is not supported any 29 | more:: 30 | 31 | SOCIAL_AUTH_EXTRA_DATA 32 | 33 | Remove ``load_extra_data`` from pipeline if needed. 34 | 35 | - Automatic email association is disabled by default since it could be 36 | a security risk and allow users to take-over others' accounts by spoofing 37 | email address in providers. Also this setting is not supported any more:: 38 | 39 | SOCIAL_AUTH_ASSOCIATE_BY_MAIL 40 | 41 | - Associate URLs are deprecated since the login ones can handle the case. This 42 | avoids issues where providers check the redirect URI and redirects to the 43 | configured value in the application. So, from now on a single entry point is 44 | recommended being:: 45 | 46 | //login// 47 | 48 | And to complete the process:: 49 | 50 | //complete// 51 | 52 | 53 | - Exceptions handling setting ``SOCIAL_AUTH_PROCESS_EXCEPTIONS`` is deprecated 54 | in favor of ``SocialAuthExceptionMiddleware`` subclassing. 55 | 56 | 57 | - The old signals ``pre_update`` and ``socialauth_registered`` are deprecated. 58 | Instead implement pipeline methods to accomplish the old functionality done 59 | by the signal handlers (or to fire any signal you want). 60 | -------------------------------------------------------------------------------- /doc/images/facebook_1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omab/django-social-auth/699571a3b6d84aa2c25ffce59daa4c7f3559a0e4/doc/images/facebook_1.jpeg -------------------------------------------------------------------------------- /doc/images/facebook_2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omab/django-social-auth/699571a3b6d84aa2c25ffce59daa4c7f3559a0e4/doc/images/facebook_2.jpeg -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to Django Social Auth's documentation! 2 | ============================================== 3 | 4 | **NOTE: THIS LIBRARY IS DEPRECATED IN FAVOR OF** `python-social-auth`_. **RIGHT NOW 5 | THIS LIBRARY DEPENDS DIRECTLY ON** `python-social-auth`_ **AND SHOULD BE CONSIDERED 6 | AS A MIGRATION STEP** 7 | 8 | Django Social Auth is an easy to setup social authentication/authorization 9 | mechanism for Django projects. 10 | 11 | Contents: 12 | 13 | .. toctree:: 14 | :maxdepth: 2 15 | 16 | intro 17 | demo 18 | installing 19 | configuration 20 | 21 | backends/index 22 | pipeline 23 | deprecated 24 | 25 | tokens 26 | contributions 27 | testing 28 | testing_tools 29 | use_cases 30 | miscellaneous 31 | bugs 32 | 33 | changelog 34 | 35 | copyrights 36 | 37 | Indices and tables 38 | ================== 39 | 40 | * :ref:`genindex` 41 | * :ref:`modindex` 42 | * :ref:`search` 43 | 44 | .. _python-social-auth: https://github.com/omab/python-social-auth 45 | -------------------------------------------------------------------------------- /doc/installing.rst: -------------------------------------------------------------------------------- 1 | 2 | Installation 3 | ============ 4 | 5 | ------------ 6 | Dependencies 7 | ------------ 8 | Dependencies that **must** be met to use the application: 9 | 10 | - OpenId_ support depends on python-openid_ 11 | 12 | - OAuth_ support depends on python-oauth2_ 13 | 14 | - Several backends demand application registration on their corresponding 15 | sites. 16 | 17 | 18 | ---------- 19 | Get a copy 20 | ---------- 21 | 22 | From pypi_:: 23 | 24 | $ pip install django-social-auth 25 | 26 | or:: 27 | 28 | $ easy_install django-social-auth 29 | 30 | or clone from github_:: 31 | 32 | $ git clone git://github.com/omab/django-social-auth.git 33 | 34 | and add social_auth to PYTHONPATH:: 35 | 36 | $ export PYTHONPATH=$PYTHONPATH:$(pwd)/django-social-auth/ 37 | 38 | or:: 39 | 40 | $ cd django-social-auth 41 | $ sudo python setup.py install 42 | 43 | 44 | .. _OpenId: http://openid.net/ 45 | .. _OAuth: http://oauth.net/ 46 | .. _pypi: http://pypi.python.org/pypi/django-social-auth/ 47 | .. _github: https://github.com/omab/django-social-auth 48 | .. _python-openid: http://pypi.python.org/pypi/python-openid/ 49 | .. _python-oauth2: https://github.com/simplegeo/python-oauth2 50 | -------------------------------------------------------------------------------- /doc/intro.rst: -------------------------------------------------------------------------------- 1 | Introduction 2 | ============ 3 | 4 | Django Social Auth is an easy way to setup social authentication/authorization 5 | mechanisms for Django projects. 6 | 7 | Crafted using base code from django-twitter-oauth_ and django-openid-auth_, 8 | it implements a common interface to define new authentication providers from 9 | third parties. 10 | 11 | 12 | -------- 13 | Features 14 | -------- 15 | This application provides user registration and login using social sites 16 | credentials. Some features are: 17 | 18 | - Registration and Login using social sites using the following providers 19 | at the moment: 20 | 21 | * `Google OpenID`_ 22 | * `Google OAuth`_ 23 | * `Google OAuth2`_ 24 | * `Yahoo OpenID`_ 25 | * OpenId_ like myOpenID_ 26 | * `Twitter OAuth`_ 27 | * `Facebook OAuth`_ 28 | * `Amazon OAuth2`_ 29 | 30 | Some contributions added support for: 31 | 32 | * `DISQUS OAuth`_ 33 | * `LiveJournal OpenID`_ 34 | * `Orkut OAuth`_ 35 | * `Linkedin OAuth`_ 36 | * `Foursquare OAuth2`_ 37 | * `GitHub OAuth`_ 38 | * `Dropbox OAuth`_ 39 | * `Flickr OAuth`_ 40 | * `VK.com OAuth`_ 41 | * `MSN Live Connect OAuth2`_ 42 | * `Skyrock OAuth`_ 43 | * `Yahoo OAuth`_ 44 | * `Evernote OAuth`_ 45 | * `Mail.ru OAuth`_ 46 | * `Odnoklassniki OAuth`_ and `Odnoklassniki IFrame applications`_ 47 | * `Mixcloud OAuth2`_ 48 | * `BitBucket OAuth`_ 49 | * `Douban OAuth`_ 50 | * `Fitbit OAuth`_ 51 | * `Instagram OAuth2`_ 52 | * `Twilio`_ 53 | * `Weibo OAuth2`_ 54 | * `Yandex OpenId`_ 55 | * `Readability OAuth`_ 56 | * `Stackoverflow OAuth2`_ 57 | * `Fedora OpenID`_ 58 | 59 | - Basic user data population and signaling, to allows custom fields values 60 | from providers response 61 | 62 | - Multiple social account associations to a single user 63 | 64 | - Custom User model override if needed (`auth.User`_ by default) 65 | 66 | - Extensible pipeline to handle authentication/association mechanism 67 | 68 | .. _auth.User: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py#L186 69 | .. _OpenId: http://openid.net/ 70 | .. _OAuth: http://oauth.net/ 71 | .. _django-twitter-oauth: https://github.com/henriklied/django-twitter-oauth 72 | .. _django-openid-auth: https://launchpad.net/django-openid-auth 73 | .. _Google OpenID: http://code.google.com/apis/accounts/docs/OpenID.html 74 | .. _Google OAuth: http://code.google.com/apis/accounts/docs/OAuth.html 75 | .. _Google OAuth2: http://code.google.com/apis/accounts/docs/OAuth2.html 76 | .. _Yahoo OpenID: http://openid.yahoo.com/ 77 | .. _myOpenID: https://www.myopenid.com/ 78 | .. _Twitter OAuth: http://dev.twitter.com/pages/oauth_faq 79 | .. _Facebook OAuth: http://developers.facebook.com/docs/authentication/ 80 | .. _DISQUS OAuth: http://disqus.com/api/docs/auth/ 81 | .. _LiveJournal OpenID: http://www.livejournal.com/support/faqbrowse.bml?faqid=283 82 | .. _Orkut OAuth: http://code.google.com/apis/orkut/docs/rest/developers_guide_protocol.html#Authenticating 83 | .. _Linkedin OAuth: https://www.linkedin.com/secure/developer 84 | .. _Foursquare OAuth2: https://developer.foursquare.com/docs/oauth.html 85 | .. _GitHub OAuth: http://developer.github.com/v3/oauth/ 86 | .. _Dropbox OAuth: https://www.dropbox.com/developers_beta/reference/api 87 | .. _Flickr OAuth: http://www.flickr.com/services/api/ 88 | .. _VK.com OAuth: http://vk.com/developers.php?oid=-1&p=%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D0%B0%D0%B9%D1%82%D0%BE%D0%B2 89 | .. _MSN Live Connect OAuth2: http://msdn.microsoft.com/en-us/library/live/hh243647.aspx 90 | .. _Skyrock OAuth: http://www.skyrock.com/developer/ 91 | .. _Yahoo OAuth: http://developer.yahoo.com/oauth/guide/oauth-auth-flow.html 92 | .. _Evernote OAuth: http://dev.evernote.com/documentation/cloud/chapters/Authentication.php 93 | .. _Mail.ru OAuth: http://api.mail.ru/docs/guides/oauth/ 94 | .. _Odnoklassniki OAuth: http://dev.odnoklassniki.ru/wiki/pages/viewpage.action?pageId=12878032 95 | .. _Odnoklassniki IFrame applications: http://dev.odnoklassniki.ru/wiki/display/ok/Odnoklassniki.ru+Third+Party+Platform 96 | .. _Mixcloud OAuth2: http://www.mixcloud.com/developers/documentation/#authorization 97 | .. _BitBucket OAuth: https://confluence.atlassian.com/display/BITBUCKET/OAuth+Consumers 98 | .. _Douban OAuth: http://www.douban.com/service/apidoc/auth 99 | .. _Fitbit OAuth: https://wiki.fitbit.com/display/API/OAuth+Authentication+in+the+Fitbit+API 100 | .. _Instagram OAuth2: http://instagram.com/developer/authentication/ 101 | .. _Twilio: https://www.twilio.com/user/account/connect/apps 102 | .. _Weibo OAuth2: http://open.weibo.com/wiki/Oauth2 103 | .. _Yandex OpenId: http://openid.yandex.ru/ 104 | .. _Readability OAuth: http://www.readability.com/developers/api 105 | .. _Stackoverflow OAuth2: http://api.stackexchange.com/ 106 | .. _Fedora OpenID: https://fedoraproject.org/wiki/OpenID 107 | .. _Amazon OAuth2: http://login.amazon.com/ 108 | -------------------------------------------------------------------------------- /doc/miscellaneous.rst: -------------------------------------------------------------------------------- 1 | Miscellaneous 2 | ============= 3 | 4 | Mailing list 5 | ------------ 6 | 7 | Join to `django-social-auth discussion list`_ and bring any questions or suggestions 8 | that would improve this application. 9 | 10 | 11 | Custom User model 12 | ----------------- 13 | 14 | If defining a custom user model, do not import ``social_auth`` from any 15 | ``models.py`` that would finally import from the ``models.py`` that defines 16 | your ``User`` class or it will make your project fail with a recursive import 17 | because ``social_auth`` uses ``get_model()`` to retrieve your User. 18 | 19 | 20 | Third party backends 21 | -------------------- 22 | 23 | There's an ongoing movement to create a list of third party backends on 24 | djangopackages.com_, so, if somebody doesn't want its backend in the 25 | ``contrib`` directory but still wants to share, just split it in a separated 26 | package and link it there. 27 | 28 | 29 | Python 2.7.2rev4, 2.7.3 and Facebook backend 30 | -------------------------------------------- 31 | 32 | It seems that this bug described in StackOverflow_ hits users using 33 | django-social-auth_ with Python versions 2.7.2rev4 and 2.7.3 (so far) and 34 | Facebook backend. The bug report `#315`_ explains it a bit more and shows 35 | a workaround fit to avoid it. 36 | 37 | 38 | Server date time 39 | ---------------- 40 | 41 | A bad date in the server might cause errors in the auth process on some services 42 | like Twitter (probably all OAuth1.0 since timestamp is passed in the parameters 43 | to request a token). 44 | 45 | This issue is usually solved by installing ``ntp`` in the server (which is 46 | a good practice to have too), and syncing the time with some ntp pool service. 47 | 48 | 49 | url Template Tag 50 | ---------------- 51 | 52 | Since Django 1.3 the URL templatetag ``{% url socialauth_begin ... %}`` syntax 53 | is deprecated in favor the new format where the URL name is quoted (using 54 | single quotes). See the `release notes`_ for details. 55 | 56 | The new syntax is not enforced yet but will be on Django 1.5, and it's also 57 | available by importing ``url`` tag from ``future`` module doing:: 58 | 59 | {% load url from future %} 60 | 61 | In case of experiencing issues similar to `#303`_, check the tag being used and 62 | its syntax. 63 | 64 | 65 | Heroku and SSL 66 | -------------- 67 | 68 | Seems that Heroku fails to pass the needed headers to indicate that the app is 69 | behind SSL, this causes troubles when building the redirect URLs used in the 70 | authentication process and providers respond with invalid redirect URL error. 71 | To enforce ``https://`` when building the URLs just define this setting:: 72 | 73 | SOCIAL_AUTH_REDIRECT_IS_HTTPS = True 74 | 75 | .. _South: http://south.aeracode.org/ 76 | .. _django-social-auth: https://github.com/omab/django-social-auth 77 | .. _djangopackages.com: http://djangopackages.com/grids/g/social-auth-backends/ 78 | .. _django-social-auth discussion list: https://groups.google.com/group/django-social-auth 79 | .. _StackOverflow: http://stackoverflow.com/questions/9835506/urllib-urlopen-works-on-sslv3-urls-with-python-2-6-6-on-1-machine-but-not-wit 80 | .. _#315: https://github.com/omab/django-social-auth/issues/315 81 | .. _release notes: https://docs.djangoproject.com/en/1.3/releases/1.3/#changes-to-url-and-ssi 82 | .. _#303: https://github.com/omab/django-social-auth/issues/303 83 | -------------------------------------------------------------------------------- /doc/pipeline.rst: -------------------------------------------------------------------------------- 1 | Authentication Pipeline 2 | ======================= 3 | 4 | The final process of the authentication workflow is handled by an operations 5 | pipeline where custom functions can be added or default items can be removed to 6 | provide a custom behavior. 7 | 8 | The default pipeline mimics the user creation and basic data gathering from 9 | previous django-social-auth_ versions and a big set of settings (listed below) 10 | that were used to alter the default behavior are now deprecated in favor of 11 | pipeline overrides. 12 | 13 | The default pipeline is composed by:: 14 | 15 | ( 16 | 'social_auth.backends.pipeline.social.social_auth_user', 17 | #'social_auth.backends.pipeline.associate.associate_by_email', 18 | 'social_auth.backends.pipeline.user.get_username', 19 | 'social_auth.backends.pipeline.user.create_user', 20 | 'social_auth.backends.pipeline.social.associate_user', 21 | 'social_auth.backends.pipeline.social.load_extra_data', 22 | 'social_auth.backends.pipeline.user.update_user_details' 23 | ) 24 | 25 | Email association (``associate_by_email`` pipeline entry) is disabled by 26 | default for security reasons. Take for instance this scenario: 27 | 28 | 1. User A registers using ``django-social-auth`` and we get email address 29 | ``foo@bar.com``. 30 | 2. User B goes to provider XXX and registers using ``foo@bar.com`` 31 | (provider XXX doesn't validate emails). 32 | 3. User B goes to your site and logs in using its XXX account using 33 | ``django-social-auth``. 34 | 4. User B gets access to User A account. 35 | 36 | If this isn't a concern for your site, just define ``SOCIAL_AUTH_PIPELINE`` 37 | like the one shown above and uncomment the line for ``associate_by_email``. 38 | 39 | But it's possible to override it by defining the setting 40 | ``SOCIAL_AUTH_PIPELINE``, for example a pipeline that won't create users, just 41 | accept already registered ones would look like this:: 42 | 43 | SOCIAL_AUTH_PIPELINE = ( 44 | 'social_auth.backends.pipeline.social.social_auth_user', 45 | 'social_auth.backends.pipeline.social.associate_user', 46 | 'social_auth.backends.pipeline.social.load_extra_data', 47 | 'social_auth.backends.pipeline.user.update_user_details' 48 | ) 49 | 50 | Each pipeline function will receive the following parameters: 51 | * Current social authentication backend 52 | * User ID given by authentication provider 53 | * User details given by authentication provider 54 | * ``is_new`` flag (initialized in ``False``) 55 | * Any arguments passed to ``auth_complete`` backend method, default views 56 | pass this arguments: 57 | - current logged in user (if it's logged in, otherwise ``None``) 58 | - current request 59 | 60 | Each pipeline entry can return a ``dict``, ``None`` or any form of 61 | ``HttpResponse`` (that includes ``HttpResponseRedirect`` too). If a ``dict`` was 62 | returned, any value in the set will be merged into the ``kwargs`` argument for 63 | the next pipeline entry, ``None`` is taken as if ``{}`` was returned, and if an 64 | ``HttpReponse`` instance was returned, it will halt the pipeline and the 65 | response will be returned to the user (check **Partial Pipeline** section below). 66 | 67 | The workflow will be cut if the exception ``social_auth.exceptions.StopPipeline`` 68 | is raised at any point. 69 | 70 | If any function returns something else beside a ``dict`` or ``None``, the 71 | workflow will be cut and the value returned immediately. This is useful to 72 | return ``HttpReponse`` instances like ``HttpResponseRedirect``. 73 | 74 | 75 | Partial Pipeline 76 | ---------------- 77 | 78 | It's possible to cut the pipeline process to return to the user asking for more 79 | data and resume the process later. To accomplish this, add the entry 80 | ``social_auth.backends.pipeline.misc.save_status_to_session`` (or a similar 81 | implementation) to the pipeline setting before any entry that returns an 82 | ``HttpResponse`` instance:: 83 | 84 | SOCIAL_AUTH_PIPELINE = ( 85 | ... 86 | social_auth.backends.pipeline.misc.save_status_to_session, 87 | app.pipeline.redirect_to_basic_user_data_form 88 | ... 89 | ) 90 | 91 | When it's time to resume the process just redirect the user to 92 | ``/complete//`` view. By default the pipeline will be resumed in the 93 | next entry after ``save_status_to_session``, but this can be modified by setting 94 | the following setting to the import path of the pipeline entry to resume 95 | processing:: 96 | 97 | SOCIAL_AUTH_PIPELINE_RESUME_ENTRY = 'social_auth.backends.pipeline.misc.save_status_to_session' 98 | 99 | ``save_status_to_session`` saves needed data into user session. The key can be 100 | defined by ``SOCIAL_AUTH_PARTIAL_PIPELINE_KEY``, which default value is 101 | ``partial_pipeline``:: 102 | 103 | SOCIAL_AUTH_PARTIAL_PIPELINE_KEY = 'partial_pipeline' 104 | 105 | Check the `example application`_ to check a basic usage. 106 | 107 | 108 | .. _django-social-auth: https://github.com/omab/django-social-auth 109 | .. _example application: https://github.com/omab/django-social-auth/blob/master/example/example/local_settings.py.template#L23 110 | -------------------------------------------------------------------------------- /doc/testing.rst: -------------------------------------------------------------------------------- 1 | Testing 2 | ======= 3 | Django-social-auth aims to be a fully tested project. Some partial tests are 4 | present at the moment and others are being worked on. 5 | 6 | To test the application just run:: 7 | 8 | ./manage.py test social_auth 9 | 10 | This will run a bunch of tests. So far only the login process is tested, but more 11 | will come eventually. 12 | 13 | User accounts on the different sites are needed to run tests, so configure the 14 | credentials in the following way:: 15 | 16 | TEST_TWITTER_USER = 'testing_account' 17 | TEST_TWITTER_PASSWORD = 'password_for_testing_account' 18 | 19 | # facebook testing 20 | TEST_FACEBOOK_USER = 'testing_account' 21 | TEST_FACEBOOK_PASSWORD = 'password_for_testing_account' 22 | 23 | # goole testing 24 | TEST_GOOGLE_USER = 'testing_account@gmail.com' 25 | TEST_GOOGLE_PASSWORD = 'password_for_testing_account' 26 | 27 | 28 | There's support for Selenium_ tests too in the root contrib directory. To run, 29 | install selenium:: 30 | 31 | $ pip install selenium 32 | 33 | and create a ``test_settings.py`` copying ``test_settings.py.template`` and 34 | fill the needed account information. Then run:: 35 | 36 | cd contrib/tests 37 | ./runtests.py 38 | 39 | .. _Selenium: http://seleniumhq.org/ 40 | -------------------------------------------------------------------------------- /doc/testing_tools.rst: -------------------------------------------------------------------------------- 1 | Testing Tools 2 | ============= 3 | 4 | django social auth provides an extension of Django's test client, SocialClient. 5 | SocialClient provides the ability for a unit test to authenticate a user 6 | through facebook. All calls to facebook are mocked. This is helpful for 7 | performing integration tests of the authentication pipeline or accessing 8 | a view that requires a user to be logged in. 9 | 10 | Example: 11 | 12 | .. code-block:: python 13 | 14 | from django.test import TestCase 15 | from social_auth.tests.client import SocialClient 16 | 17 | class SomeTestClass(TestCase): 18 | 19 | client = SocialClient 20 | user = { 21 | 'first_name': 'Django', 22 | 'last_name': 'Reinhardt', 23 | 'verified': True, 24 | 'name': 'Django Reinhardt', 25 | 'locale': 'en_US', 26 | 'hometown': { 27 | 'id': '12345678', 28 | 'name': 'Any Town, Any State' 29 | }, 30 | 'expires': '4812', 31 | 'updated_time': '2012-01-29T19:27:32+0000', 32 | 'access_token': 'dummyToken', 33 | 'link': 'http://www.facebook.com/profile.php?id=1234', 34 | 'location': { 35 | 'id': '108659242498155', 36 | 'name': 'Chicago, Illinois' 37 | }, 38 | 'gender': 'male', 39 | 'timezone': -6, 40 | 'id': '1234', 41 | 'email': 'user@domain.com' 42 | } 43 | 44 | def test_something(self): 45 | self.client.login(self.user, backend='facebook') 46 | # do something with the logged in user. 47 | -------------------------------------------------------------------------------- /doc/tokens.rst: -------------------------------------------------------------------------------- 1 | Tokens 2 | ------ 3 | 4 | Almost every service covered provides some kind of API that is protected with 5 | ``access_token`` or token pairs (like `Twitter OAuth keys`_). These tokens are 6 | gathered by the authentication mechanism and stored in 7 | ``UserSocialAuth.extra_data``. 8 | 9 | ``UserSocialAuth`` has a property named ``tokens`` to easily access these 10 | useful values, which returns a dictionary containing the token values. 11 | A simple usage example:: 12 | 13 | >>> from pprint import pprint 14 | >>> from social_auth.models import UserSocialAuth 15 | >>> instance = UserSocialAuth.objects.filter(provider='twitter').get(...) 16 | >>> pprint(instance.tokens) 17 | {u'oauth_token': u'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 18 | u'oauth_token_secret': u'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'} 19 | >>> instance = UserSocialAuth.objects.filter(provider='facebook').get(...) 20 | >>> pprint(instance.tokens) 21 | {u'access_token': u'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'} 22 | 23 | .. _Twitter OAuth keys: https://dev.twitter.com/docs/auth/authorizing-request 24 | -------------------------------------------------------------------------------- /doc/use_cases.rst: -------------------------------------------------------------------------------- 1 | Use Cases 2 | ========= 3 | 4 | Some particular use cases are listed below. 5 | 6 | Account association only 7 | ------------------------ 8 | 9 | Check the documentation about `Pipelines `_ for an example of 10 | single association, since association URLs are deprecated. 11 | 12 | 13 | Client side authorization libraries 14 | ----------------------------------- 15 | 16 | OAuth providers like Facebook provide some form of Javascript library/SDK to 17 | perform client side authorization. That authorization can be stored using 18 | django-social-auth by defining a simple view like this:: 19 | 20 | from django.contrib.auth import login 21 | from django.shortcuts import redirect 22 | from social_auth.decorators import dsa_view 23 | 24 | @dsa_view() 25 | def register_by_access_token(request, backend, *args, **kwargs): 26 | access_token = request.GET.get('access_token') 27 | user = backend.do_auth(access_token) 28 | if user and user.is_active: 29 | login(request, user) 30 | return redirect('/') 31 | 32 | This view just expects the ``access_token`` as a GET parameter and the backend 33 | name in the URL (check django-social-auth URLs). 34 | 35 | 36 | Token refreshing 37 | ---------------- 38 | 39 | OAuth2 defines a mechanism to refresh the ``access_token`` once it expires. 40 | Not all the providers support it, and some providers implement it in some way 41 | or another. Usually there's a ``refresh_token`` involved (a token that 42 | identifies the user but it's only used to retrieve a new ``access_token``). 43 | 44 | To refresh the token on a given social account just call the 45 | ``refresh_token()`` in the ``UserSocialAuth`` instance, like this:: 46 | 47 | user = User.objects.get(...) 48 | social = user.social_auth.filter(provider='google-oauth2')[0] 49 | social.refresh_token() 50 | 51 | At the moment just a few backends were tested against token refreshing 52 | (Google OAuth2, Facebook and Stripe). Other backends probably also support 53 | it (if they follow the OAuth2 standard) with the default mechanism. Others 54 | don't support it because the token is not supposed to expire. 55 | 56 | 57 | Combining associate_user and load_extra_data functions in the pipeline 58 | ---------------------------------------------------------------------- 59 | 60 | Two functions under backends.pipeline.social module, ``associate_user`` and 61 | ``load_extra_data`` are commonly used back to back in the ``SOCIAL_AUTH_PIPELINE``. 62 | Both of these modules hit the database for associating the social_user and 63 | loading extra data for this social_user. If you want to combine these two functions 64 | in order to decrease number of database visits, you can use this function:: 65 | 66 | def social_associate_and_load_data(backend, details, response, uid, user, 67 | social_user=None, *args, **kwargs): 68 | """ 69 | The combination of associate_user and load_extra_data functions 70 | of django-social-auth. The reason for combining these two pipeline 71 | functions is decreasing the number of database visits. 72 | """ 73 | extra_data = backend.extra_data(user, uid, response, details) 74 | created = False 75 | if not social_user and user: 76 | social_user, created = UserSocialAuth.objects.get_or_create( 77 | user_id=user.id, 78 | provider=backend.name, 79 | uid=uid, 80 | defaults={'extra_data': extra_data}) 81 | 82 | if not created and extra_data and social_user.extra_data != extra_data: 83 | social_user.extra_data.update(extra_data) 84 | social_user.save() 85 | return {'social_user': social_user} 86 | -------------------------------------------------------------------------------- /example/app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omab/django-social-auth/699571a3b6d84aa2c25ffce59daa4c7f3559a0e4/example/app/__init__.py -------------------------------------------------------------------------------- /example/app/facebook.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.contrib.auth import BACKEND_SESSION_KEY 3 | from django.contrib.auth.models import AnonymousUser 4 | from django.http import HttpResponse 5 | from django.shortcuts import render_to_response 6 | from django.template.context import RequestContext 7 | 8 | from django.views.decorators.csrf import csrf_exempt 9 | from django.core.cache import cache 10 | 11 | from social_auth.models import UserSocialAuth 12 | from social_auth.views import complete as social_complete 13 | from social_auth.backends.facebook import FacebookBackend 14 | 15 | 16 | def is_complete_authentication(request): 17 | return request.user.is_authenticated() and \ 18 | FacebookBackend.__name__ in request.session.get( 19 | BACKEND_SESSION_KEY, '' 20 | ) 21 | 22 | 23 | def get_access_token(user): 24 | key = str(user.id) 25 | access_token = cache.get(key) 26 | 27 | # If cache is empty read the database 28 | if access_token is None: 29 | try: 30 | social_user = user.social_user if hasattr(user, 'social_user') \ 31 | else UserSocialAuth.objects.get( 32 | user=user.id, provider=FacebookBackend.name 33 | ) 34 | except UserSocialAuth.DoesNotExist: 35 | return None 36 | 37 | if social_user.extra_data: 38 | access_token = social_user.extra_data.get('access_token') 39 | expires = social_user.extra_data.get('expires') 40 | 41 | cache.set(key, access_token, int(expires) if expires is not None 42 | else 0) 43 | return access_token 44 | 45 | 46 | # Facebook decorator to setup environment 47 | def facebook_decorator(func): 48 | def wrapper(request, *args, **kwargs): 49 | user = request.user 50 | 51 | # User must me logged via FB backend in order to ensure we talk about 52 | # the same person 53 | if not is_complete_authentication(request): 54 | try: 55 | user = social_complete(request, FacebookBackend.name) 56 | except ValueError: 57 | pass # no matter if failed 58 | 59 | # Not recommended way for FB, but still something we need to be aware 60 | # of 61 | if isinstance(user, HttpResponse): 62 | kwargs.update({'auth_response': user}) 63 | else: # Need to re-check the completion 64 | if is_complete_authentication(request): 65 | kwargs.update({'access_token': get_access_token(request.user)}) 66 | else: 67 | request.user = AnonymousUser() 68 | 69 | signed_request = FacebookBackend().load_signed_request( 70 | request.REQUEST.get('signed_request', '') 71 | ) 72 | if signed_request: 73 | kwargs.update({'signed_request': signed_request}) 74 | 75 | return func(request, *args, **kwargs) 76 | 77 | return wrapper 78 | 79 | 80 | @csrf_exempt 81 | @facebook_decorator 82 | def facebook_view(request, *args, **kwargs): 83 | # If there is a ready response just return it. Not recommended though. 84 | auth_response = kwargs.get('auth_response') 85 | if auth_response: 86 | return auth_response 87 | return render_to_response('facebook.html', { 88 | 'fb_app_id': getattr(settings, 'FACEBOOK_APP_ID', None), 89 | 'warning': request.method == 'GET' 90 | }, RequestContext(request)) 91 | -------------------------------------------------------------------------------- /example/app/models.py: -------------------------------------------------------------------------------- 1 | # Define a custom User class to work with django-social-auth 2 | from django.db import models 3 | 4 | 5 | class CustomUserManager(models.Manager): 6 | def create_user(self, username, email): 7 | return self.model._default_manager.create(username=username) 8 | 9 | 10 | class CustomUser(models.Model): 11 | username = models.CharField(max_length=128) 12 | last_login = models.DateTimeField(blank=True, null=True) 13 | 14 | objects = CustomUserManager() 15 | 16 | def is_authenticated(self): 17 | return True 18 | -------------------------------------------------------------------------------- /example/app/odnoklassniki.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | from django.conf import settings 3 | from django.contrib.auth import BACKEND_SESSION_KEY, logout 4 | from django.contrib.auth.models import AnonymousUser 5 | from django.http import HttpResponse 6 | from django.shortcuts import redirect 7 | from django.views.generic.base import TemplateView 8 | from social_auth.views import complete 9 | 10 | SANDBOX_URL = 'http://api-sandbox.odnoklassniki.ru:8088/sandbox/protected/application/launch.do?appId={0:s}&userId=0' 11 | class OdnoklassnikiInfo(TemplateView): 12 | template_name = 'odnoklassniki_info.html' 13 | 14 | def get(self, *args, **kwargs): 15 | if hasattr(settings, 'ODNOKLASSNIKI_APP_ID'): 16 | return redirect(SANDBOX_URL.format(settings.ODNOKLASSNIKI_APP_ID)) 17 | else: 18 | return super(OdnoklassnikiInfo, self).get(*args, **kwargs) 19 | 20 | ok_app_info = OdnoklassnikiInfo.as_view() 21 | 22 | class OdnoklassnikiApp(TemplateView): 23 | template_name = 'odnoklassniki.html' 24 | 25 | def get(self, request, *args, **kwargs): 26 | result = None 27 | if request.GET.get('apiconnection', None): 28 | if request.user.is_authenticated() and 'OdnoklassnikiAppBackend' not in request.session.get(BACKEND_SESSION_KEY, ''): 29 | logout(request) 30 | result = complete(request, 'odnoklassnikiapp') 31 | if isinstance(result, HttpResponse): 32 | return result 33 | else: 34 | if not request.user.is_authenticated() or 'OdnoklassnikiAppBackend' not in request.session.get(BACKEND_SESSION_KEY, ''): 35 | request.user = AnonymousUser() 36 | 37 | context = self.get_context_data(params=kwargs) 38 | return self.render_to_response(context) 39 | 40 | ok_app = OdnoklassnikiApp.as_view() -------------------------------------------------------------------------------- /example/app/pipeline.py: -------------------------------------------------------------------------------- 1 | from django.http import HttpResponseRedirect 2 | 3 | 4 | def redirect_to_form(strategy, user=None, *args, **kwargs): 5 | if not strategy.session_get('saved_username') and user is None: 6 | return HttpResponseRedirect('/form/') 7 | 8 | 9 | def username(strategy, user=None, *args, **kwargs): 10 | if user: 11 | username = user.username 12 | else: 13 | username = strategy.session_get('saved_username') 14 | return {'username': username} 15 | 16 | 17 | def redirect_to_form2(strategy, *args, **kwargs): 18 | if strategy.session_get('saved_first_name'): 19 | return HttpResponseRedirect('/form2/') 20 | 21 | 22 | def first_name(strategy, *args, **kwargs): 23 | if strategy.session_get('saved_first_name'): 24 | user = kwargs['user'] 25 | user.first_name = strategy.session_get('saved_first_name') 26 | user.save() 27 | -------------------------------------------------------------------------------- /example/app/views.py: -------------------------------------------------------------------------------- 1 | from django.http import HttpResponseRedirect 2 | from django.contrib.auth import logout as auth_logout 3 | from django.contrib.auth.decorators import login_required 4 | from django.template import RequestContext 5 | from django.shortcuts import render_to_response, redirect 6 | from django.contrib.messages.api import get_messages 7 | 8 | from social_auth import __version__ as version 9 | 10 | 11 | def home(request): 12 | """Home view, displays login mechanism""" 13 | if request.user.is_authenticated(): 14 | return HttpResponseRedirect('done') 15 | else: 16 | return render_to_response('home.html', {'version': version}, 17 | RequestContext(request)) 18 | 19 | 20 | @login_required 21 | def done(request): 22 | """Login complete view, displays user data""" 23 | ctx = { 24 | 'version': version, 25 | 'last_login': request.session.get('social_auth_last_login_backend') 26 | } 27 | return render_to_response('done.html', ctx, RequestContext(request)) 28 | 29 | 30 | def error(request): 31 | """Error view""" 32 | messages = get_messages(request) 33 | return render_to_response('error.html', {'version': version, 34 | 'messages': messages}, 35 | RequestContext(request)) 36 | 37 | 38 | def logout(request): 39 | """Logs out user""" 40 | auth_logout(request) 41 | return HttpResponseRedirect('/') 42 | 43 | 44 | def form(request): 45 | if request.method == 'POST' and request.POST.get('username'): 46 | request.session['saved_username'] = request.POST['username'] 47 | backend = request.session['partial_pipeline']['backend'] 48 | return redirect('socialauth_complete', backend=backend) 49 | return render_to_response('form.html', {}, RequestContext(request)) 50 | 51 | 52 | def form2(request): 53 | if request.method == 'POST' and request.POST.get('first_name'): 54 | request.session['saved_first_name'] = request.POST['first_name'] 55 | backend = request.session['partial_pipeline']['backend'] 56 | return redirect('socialauth_complete', backend=backend) 57 | return render_to_response('form2.html', {}, RequestContext(request)) 58 | 59 | 60 | def close_login_popup(request): 61 | return render_to_response('close_popup.html', {}, RequestContext(request)) 62 | -------------------------------------------------------------------------------- /example/app/vkontakte.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import BACKEND_SESSION_KEY 2 | from django.contrib.auth.models import AnonymousUser 3 | from django.http import HttpResponse 4 | from django.shortcuts import render_to_response 5 | from django.template.context import RequestContext 6 | 7 | from django.core.cache import cache 8 | from django.conf import settings 9 | 10 | from social_auth.models import UserSocialAuth 11 | from social_auth.views import complete as social_complete 12 | from social_auth.backends.contrib.vk import VKOAuth2Backend 13 | 14 | 15 | def is_complete_authentication(request): 16 | return request.user.is_authenticated() and \ 17 | VKOAuth2Backend.__name__ in request.session.get( 18 | BACKEND_SESSION_KEY, '' 19 | ) 20 | 21 | 22 | def get_access_token(user): 23 | key = str(user.id) 24 | access_token = cache.get(key) 25 | 26 | # If cache is empty read the database 27 | if access_token is None: 28 | try: 29 | social_user = user.social_user if hasattr(user, 'social_user') \ 30 | else UserSocialAuth.objects.get( 31 | user=user.id, 32 | provider=VKOAuth2Backend.name 33 | ) 34 | except UserSocialAuth.DoesNotExist: 35 | return None 36 | 37 | if social_user.extra_data: 38 | access_token = social_user.extra_data.get('access_token') 39 | expires = social_user.extra_data.get('expires') 40 | 41 | cache.set(key, access_token, int(expires) if expires is not None 42 | else 0) 43 | return access_token 44 | 45 | 46 | # VK decorator to setup environment 47 | def vkontakte_decorator(func): 48 | def wrapper(request, *args, **kwargs): 49 | user = request.user 50 | 51 | # User must me logged via VKontakte backend in order to ensure we talk 52 | # about the same person 53 | if not is_complete_authentication(request): 54 | try: 55 | user = social_complete(request, VKOAuth2Backend.name) 56 | except (ValueError, AttributeError): 57 | pass # no matter if failed 58 | 59 | # Not recommended way for VK, but still something we need to be aware 60 | # of 61 | if isinstance(user, HttpResponse): 62 | kwargs.update({'auth_response': user}) 63 | else: # Need to re-check the completion 64 | if is_complete_authentication(request): 65 | kwargs.update({'access_token': get_access_token(request.user)}) 66 | else: 67 | request.user = AnonymousUser() 68 | 69 | return func(request, *args, **kwargs) 70 | 71 | return wrapper 72 | 73 | 74 | @vkontakte_decorator 75 | def vkontakte_view(request, *args, **kwargs): 76 | # If there is a ready response just return it. Not recommended because 77 | # pipeline redirects fail the normal workflow here. 78 | auth_response = kwargs.get('auth_response') 79 | if auth_response: 80 | for item in auth_response.items(): 81 | if item[0] == 'Location' and 'form' in item[1]: 82 | return auth_response 83 | 84 | return render_to_response('vkontakte_app.html', { 85 | 'vk_app_id': settings.VKONTAKTE_APP_AUTH['id'] 86 | if hasattr(settings, 'VKONTAKTE_APP_AUTH') else None, 87 | 'app_scope': ','.join(settings.VKONTAKTE_OAUTH2_EXTRA_SCOPE), 88 | 'warning': not request.GET.get('user_id') 89 | }, RequestContext(request)) 90 | -------------------------------------------------------------------------------- /example/example/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omab/django-social-auth/699571a3b6d84aa2c25ffce59daa4c7f3559a0e4/example/example/__init__.py -------------------------------------------------------------------------------- /example/example/local_settings.py.template: -------------------------------------------------------------------------------- 1 | TWITTER_CONSUMER_KEY = '' 2 | TWITTER_CONSUMER_SECRET = '' 3 | FACEBOOK_APP_ID = '' 4 | FACEBOOK_API_SECRET = '' 5 | LINKEDIN_CONSUMER_KEY = '' 6 | LINKEDIN_CONSUMER_SECRET = '' 7 | SKYROCK_CONSUMER_KEY = '' 8 | SKYROCK_CONSUMER_SECRET = '' 9 | ORKUT_CONSUMER_KEY = '' 10 | ORKUT_CONSUMER_SECRET = '' 11 | GOOGLE_OAUTH2_CLIENT_ID = '' 12 | GOOGLE_OAUTH2_CLIENT_SECRET = '' 13 | SOCIAL_AUTH_CREATE_USERS = True 14 | SOCIAL_AUTH_FORCE_RANDOM_USERNAME = False 15 | SOCIAL_AUTH_DEFAULT_USERNAME = 'socialauth_user' 16 | SOCIAL_AUTH_COMPLETE_URL_NAME = 'socialauth_complete' 17 | LOGIN_ERROR_URL = '/login/error/' 18 | VKONTAKTE_APP_ID = '' 19 | VKONTAKTE_APP_SECRET = '' 20 | # Usage for applications auth: {'key': application_key, 'user_mode': 0 (default) | 1 (check) | 2 (online check) } 21 | # 0 means is_app_user request parameter is ignored, 1 - must be = 1, 2 - checked via VK API request (useful when user 22 | # connects to your application on app page and you reload the iframe) 23 | VKONTAKTE_APP_AUTH = None 24 | ODNOKLASSNIKI_OAUTH2_CLIENT_KEY = '' 25 | ODNOKLASSNIKI_OAUTH2_APP_KEY = '' 26 | ODNOKLASSNIKI_OAUTH2_CLIENT_SECRET = '' 27 | MAILRU_OAUTH2_CLIENT_KEY = '' 28 | MAILRU_OAUTH2_APP_KEY = '' 29 | MAILRU_OAUTH2_CLIENT_SECRET = '' 30 | #SOCIAL_AUTH_USER_MODEL = 'app.CustomUser' 31 | SOCIAL_AUTH_ERROR_KEY = 'socialauth_error' 32 | GITHUB_APP_ID = '' 33 | GITHUB_API_SECRET = '' 34 | FOURSQUARE_CONSUMER_KEY = '' 35 | FOURSQUARE_CONSUMER_SECRET = '' 36 | DOUBAN_CONSUMER_KEY = '' 37 | DOUBAN_CONSUMER_SECRET = '' 38 | YANDEX_OAUTH2_CLIENT_KEY = '' 39 | YANDEX_OAUTH2_CLIENT_SECRET = '' 40 | YANDEX_OAUTH2_API_URL = 'https://api-yaru.yandex.ru/me/' # http://api.moikrug.ru/v1/my/ for Moi Krug 41 | DAILYMOTION_OAUTH2_KEY = '' 42 | DAILYMOTION_OAUTH2_SECRET = '' 43 | SHOPIFY_APP_API_KEY = '' 44 | SHOPIFY_SHARED_SECRET = '' 45 | STOCKTWITS_CONSUMER_KEY = '' 46 | STOCKTWITS_CONSUMER_SECRET = '' 47 | READABILITY_CONSUMER_KEY = '' 48 | READABILITY_CONSUMER_SECRET = '' 49 | 50 | # Backward compatibility 51 | YANDEX_APP_ID = YANDEX_OAUTH2_CLIENT_KEY 52 | YANDEX_API_SECRET = YANDEX_OAUTH2_CLIENT_SECRET 53 | 54 | VK_APP_ID = VKONTAKTE_APP_ID 55 | VK_API_SECRET = VKONTAKTE_APP_SECRET 56 | # VKONTAKTE_APP_AUTH={'key':'iframe_app_secret_key', 'user_mode': 2, 'id':'iframe_app_id'} 57 | 58 | SOCIAL_AUTH_FORCE_POST_DISCONNECT = True 59 | 60 | SOCIAL_AUTH_PIPELINE = ( 61 | 'social_auth.backends.pipeline.social.social_auth_user', 62 | 'social_auth.backends.pipeline.associate.associate_by_email', 63 | 'social_auth.backends.pipeline.misc.save_status_to_session', 64 | 'app.pipeline.redirect_to_form', 65 | 'app.pipeline.username', 66 | 'social_auth.backends.pipeline.user.create_user', 67 | 'social_auth.backends.pipeline.social.associate_user', 68 | 'social_auth.backends.pipeline.social.load_extra_data', 69 | 'social_auth.backends.pipeline.user.update_user_details', 70 | ) 71 | -------------------------------------------------------------------------------- /example/example/middleware.py: -------------------------------------------------------------------------------- 1 | from django.core.urlresolvers import reverse 2 | 3 | from social_auth.exceptions import AuthAlreadyAssociated 4 | from social_auth.middleware import SocialAuthExceptionMiddleware 5 | 6 | 7 | class ExampleSocialAuthExceptionMiddleware(SocialAuthExceptionMiddleware): 8 | def raise_exception(self, request, exception): 9 | return False 10 | 11 | def get_message(self, request, exception): 12 | if isinstance(exception, AuthAlreadyAssociated): 13 | return 'Somebody is already using that account!' 14 | return super(ExampleSocialAuthExceptionMiddleware, self)\ 15 | .get_message(request, exception) 16 | 17 | def get_redirect_uri(self, request, exception): 18 | if request.user.is_authenticated(): 19 | return reverse('done') 20 | else: 21 | return reverse('error') 22 | -------------------------------------------------------------------------------- /example/example/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: /login/ 3 | Disallow: /logout/ 4 | Disallow: /associate/ 5 | Disallow: /done/ 6 | Disallow: /error/ 7 | Disallow: /admin/ 8 | Disallow: /complete/ 9 | -------------------------------------------------------------------------------- /example/example/settings.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from os.path import abspath, dirname, basename, join 3 | 4 | 5 | #try: 6 | #import social_auth 7 | #social_auth # pyflakes 8 | #except ImportError: 9 | #import sys 10 | # sys.path.insert(0, '..') 11 | 12 | sys.path.insert(0, '..') 13 | sys.path.insert(0, '../../python-social-auth') 14 | 15 | 16 | DEBUG = True 17 | TEMPLATE_DEBUG = DEBUG 18 | 19 | ROOT_PATH = abspath(dirname(__file__)) 20 | PROJECT_NAME = basename(ROOT_PATH) 21 | 22 | ADMINS = () 23 | MANAGERS = ADMINS 24 | 25 | DATABASES = { 26 | 'default': { 27 | 'ENGINE': 'django.db.backends.sqlite3', 28 | 'NAME': 'test.db' 29 | } 30 | } 31 | 32 | TIME_ZONE = 'America/Chicago' 33 | LANGUAGE_CODE = 'en-us' 34 | SITE_ID = 1 35 | USE_I18N = True 36 | USE_L10N = True 37 | USE_TZ = True 38 | MEDIA_ROOT = '' 39 | MEDIA_URL = '' 40 | STATIC_ROOT = '' 41 | STATIC_URL = '/static/' 42 | 43 | STATICFILES_DIRS = ( 44 | # Put strings here, like "/home/html/static" or "C:/www/django/static". 45 | # Always use forward slashes, even on Windows. 46 | # Don't forget to use absolute paths, not relative paths. 47 | ) 48 | 49 | STATICFILES_FINDERS = ( 50 | 'django.contrib.staticfiles.finders.FileSystemFinder', 51 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 52 | # 'django.contrib.staticfiles.finders.DefaultStorageFinder', 53 | ) 54 | 55 | SECRET_KEY = '_u6ym67ywnj0ugi2=6f-a_361i6o5elx91hftz$+klw)(*pqjw' 56 | 57 | TEMPLATE_LOADERS = ( 58 | 'django.template.loaders.filesystem.Loader', 59 | 'django.template.loaders.app_directories.Loader', 60 | # 'django.template.loaders.eggs.Loader', 61 | ) 62 | 63 | MIDDLEWARE_CLASSES = ( 64 | 'django.middleware.common.CommonMiddleware', 65 | 'django.contrib.sessions.middleware.SessionMiddleware', 66 | 'django.middleware.csrf.CsrfViewMiddleware', 67 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 68 | 'django.contrib.messages.middleware.MessageMiddleware', 69 | # Uncomment the next line for simple clickjacking protection: 70 | # 'django.middleware.clickjacking.XFrameOptionsMiddleware', 71 | ) 72 | 73 | ROOT_URLCONF = 'example.urls' 74 | 75 | WSGI_APPLICATION = 'example.wsgi.application' 76 | 77 | TEMPLATE_DIRS = ( 78 | join(ROOT_PATH, 'templates'), 79 | ) 80 | 81 | INSTALLED_APPS = ( 82 | 'django.contrib.auth', 83 | 'django.contrib.contenttypes', 84 | 'django.contrib.sessions', 85 | 'django.contrib.sites', 86 | 'django.contrib.messages', 87 | 'django.contrib.staticfiles', 88 | 'django.contrib.admin', 89 | 'south', 90 | # 'social.apps.django_app.default', 91 | 'social_auth', 92 | 'app', 93 | ) 94 | 95 | LOGGING = { 96 | 'version': 1, 97 | 'disable_existing_loggers': False, 98 | 'filters': { 99 | 'require_debug_false': { 100 | '()': 'django.utils.log.RequireDebugFalse' 101 | } 102 | }, 103 | 'handlers': { 104 | 'mail_admins': { 105 | 'level': 'ERROR', 106 | 'filters': ['require_debug_false'], 107 | 'class': 'django.utils.log.AdminEmailHandler' 108 | } 109 | }, 110 | 'loggers': { 111 | 'django.request': { 112 | 'handlers': ['mail_admins'], 113 | 'level': 'ERROR', 114 | 'propagate': True, 115 | }, 116 | } 117 | } 118 | 119 | AUTHENTICATION_BACKENDS = ( 120 | 'social_auth.backends.OpenIDBackend', 121 | 'social_auth.backends.twitter.TwitterBackend', 122 | 'social_auth.backends.facebook.FacebookBackend', 123 | 'social_auth.backends.google.GoogleOAuthBackend', 124 | 'social_auth.backends.google.GoogleOAuth2Backend', 125 | 'social_auth.backends.google.GoogleBackend', 126 | 'social_auth.backends.yahoo.YahooBackend', 127 | 'social_auth.backends.stripe.StripeBackend', 128 | 'social_auth.backends.steam.SteamBackend', 129 | 'social_auth.backends.reddit.RedditBackend', 130 | 'social_auth.backends.amazon.AmazonBackend', 131 | 'social_auth.backends.browserid.BrowserIDBackend', 132 | 'social_auth.backends.contrib.linkedin.LinkedinBackend', 133 | 'social_auth.backends.contrib.skyrock.SkyrockBackend', 134 | 'social_auth.backends.contrib.flickr.FlickrBackend', 135 | 'social_auth.backends.contrib.instagram.InstagramBackend', 136 | 'social_auth.backends.contrib.github.GithubBackend', 137 | 'social_auth.backends.contrib.yandex.YandexBackend', 138 | 'social_auth.backends.contrib.yandex.YandexOAuth2Backend', 139 | 'social_auth.backends.contrib.yandex.YaruBackend', 140 | 'social_auth.backends.contrib.disqus.DisqusBackend', 141 | 'social_auth.backends.contrib.yahoo.YahooOAuthBackend', 142 | 'social_auth.backends.contrib.foursquare.FoursquareBackend', 143 | 'social_auth.backends.contrib.live.LiveBackend', 144 | 'social_auth.backends.contrib.livejournal.LiveJournalBackend', 145 | 'social_auth.backends.contrib.douban.DoubanBackend', 146 | 'social_auth.backends.contrib.vk.VKOpenAPIBackend', 147 | 'social_auth.backends.contrib.vk.VKOAuth2Backend', 148 | 'social_auth.backends.contrib.odnoklassniki.OdnoklassnikiBackend', 149 | 'social_auth.backends.contrib.odnoklassniki.OdnoklassnikiAppBackend', 150 | 'social_auth.backends.contrib.mailru.MailruBackend', 151 | 'social_auth.backends.contrib.dailymotion.DailymotionBackend', 152 | # 'social_auth.backends.contrib.shopify.ShopifyBackend', 153 | # 'social_auth.backends.contrib.exacttarget.ExactTargetBackend', 154 | 'social_auth.backends.contrib.stocktwits.StocktwitsBackend', 155 | 'social_auth.backends.contrib.behance.BehanceBackend', 156 | 'social_auth.backends.contrib.readability.ReadabilityBackend', 157 | 'social_auth.backends.contrib.fedora.FedoraBackend', 158 | 'django.contrib.auth.backends.ModelBackend', 159 | ) 160 | 161 | TEMPLATE_CONTEXT_PROCESSORS = ( 162 | 'django.contrib.auth.context_processors.auth', 163 | 'django.core.context_processors.debug', 164 | 'django.core.context_processors.i18n', 165 | 'django.core.context_processors.media', 166 | 'django.contrib.messages.context_processors.messages', 167 | 'social_auth.context_processors.social_auth_by_type_backends', 168 | ) 169 | 170 | LOGIN_REDIRECT_URL = '/' 171 | 172 | SOCIAL_AUTH_PIPELINE = ( 173 | 'social.pipeline.social_auth.social_details', 174 | 'social.pipeline.social_auth.social_uid', 175 | 'social.pipeline.social_auth.auth_allowed', 176 | 'social_auth.backends.pipeline.social.social_auth_user', 177 | 'social_auth.backends.pipeline.associate.associate_by_email', 178 | 'social_auth.backends.pipeline.misc.save_status_to_session', 179 | 'app.pipeline.redirect_to_form', 180 | 'app.pipeline.username', 181 | 'social_auth.backends.pipeline.user.create_user', 182 | 'social_auth.backends.pipeline.social.associate_user', 183 | 'social_auth.backends.pipeline.social.load_extra_data', 184 | 'social_auth.backends.pipeline.user.update_user_details', 185 | 'social_auth.backends.pipeline.misc.save_status_to_session', 186 | 'app.pipeline.redirect_to_form2', 187 | 'app.pipeline.first_name', 188 | ) 189 | 190 | try: 191 | from example.local_settings import * 192 | except Exception as e: 193 | pass 194 | -------------------------------------------------------------------------------- /example/example/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Django Social Auth 5 | 6 | 7 | 8 | 32 | 33 | {% block script %}{% endblock %} 34 | 35 | 36 |

Django Social Auth (v{{ version }})

37 |

38 | Django Social Auth is an easy to setup social authentication/registration mechanism for Django projects. 39 |

40 |

Check the documentation on Github

41 | 42 |

{% block heading %}{% endblock %}

43 | {% if messages %} 44 |
    45 | {% for message in messages %} 46 | {{ message }} 47 | {% endfor %} 48 |
49 | {% endif %} 50 | 51 |
52 | {% block content %}{% endblock %} 53 |
54 | 55 |
Fork me on GitHub
56 | 57 | 58 | -------------------------------------------------------------------------------- /example/example/templates/close_popup.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block heading %}Login popup{% endblock %} 4 | 5 | {% block script %} 6 | 22 | 23 | {% endblock %} 24 | -------------------------------------------------------------------------------- /example/example/templates/done.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block script %} 5 | 6 | 7 | {% endblock %} 8 | 9 | {% block heading %}Logged in!{% endblock %} 10 | 11 | {% block content %} 12 |
13 |

User data:

14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
Id: {{ user.id }}
Username: {{ user.username }}
Email: {{ user.email|default:"Not provided" }}
First name: {{ user.first_name|default:"Not provided" }}
Last name: {{ user.last_name|default:"Not provided" }}
Last login backend: {{ last_login }}
22 |
23 | 24 |
25 | {% if social_auth.associated %} 26 |

Disconnect accounts

27 | 41 | {% endif %} 42 | 43 |

Associate new OAuth credentials:

44 |
    45 | {% for name in social_auth.backends.oauth %} 46 |
  • {{ name|title }}
  • 47 | {% endfor %} 48 |
49 | 50 |

Associate new OAuth2 credentials:

51 |
    52 | {% for name in social_auth.backends.oauth2 %} 53 |
  • {{ name|title }}
  • 54 | {% endfor %} 55 |
56 | 57 |

Associate new OpenId credentials:

58 |
    59 | {% for name in social_auth.backends.openid %} 60 |
  • 61 | {% if name != "livejournal" and name != "openid" %} 62 | {{ name|title }} 63 | {% else %} 64 | {% if name == "livejournal" %} 65 |
    {% csrf_token %} 66 |
    67 | 68 | 69 | 70 |
    71 |
    72 | {% else %} 73 | {% if name == "openid" %} 74 |
    {% csrf_token %} 75 |
    76 | 77 | 78 | 79 |
    80 |

    Like your personal myopenid

    81 |
    82 | {% endif %} 83 | {% endif %} 84 | {% endif %} 85 |
  • 86 | {% endfor %} 87 |
88 | 89 |

Associate new BrowserID:

90 |
91 | 92 | BrowserID 93 | 113 |
114 |
115 | 116 |
117 | Logout 118 |
119 | 120 | 128 | {% endblock %} 129 | -------------------------------------------------------------------------------- /example/example/templates/error.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block heading %}Error!{% endblock %} 4 | 5 | {% block content %} 6 |
7 |

Sorry but some error made you impossible to login.

8 | 9 | {% if messages %} 10 | {% for msg in messages %} 11 |

{{ msg.message }} ({{ msg.extra_tags }})

12 | {% endfor %} 13 | {% endif %} 14 | {% if error_msg %} 15 |

Details:

16 |

{{ error_msg }}

17 | {% endif %} 18 | 19 |

Please try again Home

20 |
21 | {% endblock %} 22 | -------------------------------------------------------------------------------- /example/example/templates/facebook.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block script %} 4 | 17 | {% endblock %} 18 | 19 | {% block heading %}Facebook Canvas Application Authentication{% endblock %} 20 | {% block content %} 21 | {% if user.is_anonymous %} 22 | {% if warning %} 23 |

You are using GET request to this page, and this is not something Facebook usually does. 24 | To make a real test you need to do following: 25 |

26 |
    27 |
  1. Create your canvas application at Facebook.
  2. 28 |
  3. In Facebook application settings specify your canvas URL mysite.com/fb (current default).
  4. 29 |
  5. Setup your Django Social Auth settings like you usually do for Facebook authentication (FACEBOOK_APP_ID etc).
  6. 30 |
  7. Launch manage.py via sudo ./manage.py mysite.com:80 for browser to be able to load it when Facebook calls canvas URL.
  8. 31 |
  9. Open your Facebook page via apps.facebook.com/app_namespace or better via www.facebook.com/pages/user-name/user-id?sk=app_app-id
  10. 32 |
  11. After that you will see this page in a right way and will able to connect to application and login automatically after connection.
  12. 33 |
34 | {% else %} 35 |

You are a guest in this Facebook application.

36 | Click to connect and authenticate 37 | {% endif %} 38 | {% else %} 39 |

Authenticated successfully as {{ user }}

40 | Done 41 | {% endif %} 42 | 43 |
44 | 60 | {% endblock %} -------------------------------------------------------------------------------- /example/example/templates/form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block heading %}User basic form{% endblock %} 4 | 5 | {% block content %} 6 |
7 | {% csrf_token %} 8 |

9 | 10 | 11 |

12 | 13 | 14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /example/example/templates/form2.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block heading %}User basic form2{% endblock %} 4 | 5 | {% block content %} 6 |
7 | {% csrf_token %} 8 |

9 | 10 | 11 |

12 | 13 | 14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /example/example/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block script %} 5 | 6 | 7 | 8 | 22 | 23 | {% endblock %} 24 | 25 | {% block heading %}Login using any of the following methods{% endblock %} 26 | 27 | {% block content %} 28 |
29 |

Login using OAuth from:

30 |
    31 | {% for name in social_auth.backends.oauth %} 32 |
  • {{ name|title }}
  • 33 | {% endfor %} 34 |
35 |
36 | 37 |
38 |

Login using OAuth2 from:

39 |
    40 | {% for name in social_auth.backends.oauth2 %} 41 |
  • {{ name|title }}
  • 42 | {% endfor %} 43 |
44 |
45 | 46 |
47 |

Login using OpenId from:

48 |
    49 | {% for name in social_auth.backends.openid %} 50 |
  • 51 | {% if name != "livejournal" and name != "openid" %} 52 | {{ name|title }} 53 | {% else %} 54 | {% if name == "livejournal" %} 55 |
    {% csrf_token %} 56 |
    57 | 58 | 59 | 60 |
    61 |
    62 | {% else %} 63 | {% if name == "openid" %} 64 |
    {% csrf_token %} 65 |
    66 | 67 | 68 | 69 |
    70 |

    Like your personal myopenid

    71 |
    72 | {% endif %} 73 | {% endif %} 74 | {% endif %} 75 |
  • 76 | {% endfor %} 77 |
78 |
79 | 80 |
81 |

Login using BrowserID:

82 |
83 | 84 | BrowserID 85 | 105 |
106 |
107 | 108 |
109 | 110 | {% if social_auth.backends.oauth2 %} 111 |
112 |

Login in pop-up window:

113 |
    114 | {% with social_auth.backends.oauth2|first as first_name %} 115 |
  • Some OAuth2 backend: {{ first_name|title }}
  • 116 | {% endwith %} 117 |
118 |
119 | {% endif %} 120 | 121 |
122 |

Login using other authentication systems:

123 | 129 |
130 | {% endblock %} 131 | -------------------------------------------------------------------------------- /example/example/templates/odnoklassniki.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | {% if user.is_authenticated %} 5 | Hello! You've successfully authenticated within your Odnoklassniki app. I know you, your name is {{ user.get_full_name }}! 6 | {% else %} 7 | Hello! Something went wrong and you're still seem to be anonymous for me. 8 | {% endif %} 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /example/example/templates/odnoklassniki_info.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |

This demo works with Sandbox mode only.

5 |

6 | Please set

ODNOKLASSNIKI_APP_ID
,
ODNOKLASSNIKI_APP_PUBLIC_KEY
and
ODNOKLASSNIKI_APP_SECRET
in 7 | your
settings.py
. Also set
LOGIN_URL = '/ok/'
Then edit your sandbox app that it point to the 8 |
http://localhost:8000/ok/
, start your server with
python manage.py runserver
and open your sandbox app. 9 | You should see the name of your sandbox user. 10 |

11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /example/example/templates/vkontakte.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block heading %}VKontakte login{% endblock %} 4 | 5 | {% block content %} 6 | 7 | 8 | 9 | 35 | 36 |

37 | Click to authorize 38 |

39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /example/example/templates/vkontakte_app.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block heading %}VKontakte application authentication{% endblock %} 4 | 5 | {% block content %} 6 | 7 | 8 | 9 | 29 | 30 | {% if user.is_anonymous %} 31 | {% if warning %} 32 |

GET request does not contain user_id and this is not something VKontakte usually does. 33 | Probably you do not use VKontakte to open this page. To do a real test you need to do following: 34 |

35 |
    36 |
  1. Create your IFrame application at VKontakte.
  2. 37 |
  3. In your application settings specify your IFrame URL mysite.com/vk (current default).
  4. 38 |
  5. Because VK IFrame uses other app ID than OAuth/OpenAPI authentication one, you have to specify it and its secret key in VKAPP_* settings:
  6. 39 |
  7. VKAPP_APP_ID='iframe_app_id', VKAPP_API_SECRET='iframe_app_secret_key', VKAPP_USER_MODE = 'user_mode'
  8. 40 |
  9. user_mode values
  10. 41 |
      42 |
    1. if 0 there will be no check whether a user connected to your application or not
    2. 43 |
    3. if 1 DSA will check is_app_user parameter VKontakte sends when user opens app page one time
    4. 44 |
    5. if 2 (safest) DSA will check status of user interactively (useful when you have interactive authentication via AJAX)
    6. 45 |
    46 |
  11. Launch manage.py via sudo ./manage.py mysite.com:80 for browser to be able to load it when VKontakte calls IFrame URL.
  12. 47 |
  13. Open your VKontakte app page via http://vk.com/appapp_id
  14. 48 |
  15. After that you will see this page in a right way and will able to connect to application and login automatically after connection.
  16. 49 |
50 | {% else %} 51 |

You are not authenticated at VKontakte.

52 | Click to authenticate 53 | {% endif %} 54 | {% else %} 55 |

Authenticated successfully as {{ user }}

56 | Done 57 | 58 | {% endif %} 59 | 60 | {% endblock %} 61 | -------------------------------------------------------------------------------- /example/example/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import patterns, url, include 2 | from django.contrib import admin 3 | 4 | from app.views import home, done, logout, error, form, form2, close_login_popup 5 | from app.facebook import facebook_view 6 | from app.vkontakte import vkontakte_view 7 | from app.odnoklassniki import ok_app, ok_app_info 8 | 9 | admin.autodiscover() 10 | 11 | 12 | urlpatterns = patterns('', 13 | url(r'^$', home, name='home'), 14 | url(r'^done/$', done, name='done'), 15 | url(r'^error/$', error, name='error'), 16 | url(r'^logout/$', logout, name='logout'), 17 | url(r'^form/$', form, name='form'), 18 | url(r'^form2/$', form2, name='form2'), 19 | url(r'^admin/', include(admin.site.urls)), 20 | url(r'^fb/', facebook_view, name='fb_app'), 21 | url(r'^vk/', vkontakte_view, name='vk_app'), 22 | url(r'^ok/$', ok_app, name='ok_app'), 23 | url(r'^ok/info/$', ok_app_info, name='ok_app_info'), 24 | url(r'^close_login_popup/$', close_login_popup, name='login_popup_close'), 25 | url(r'', include('social_auth.urls')), 26 | ) 27 | -------------------------------------------------------------------------------- /example/example/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for example 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/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 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | django>=1.2.5 2 | python-social-auth>=0.1.12 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Setup file for easy installation""" 3 | from os.path import join, dirname 4 | from setuptools import setup 5 | 6 | 7 | version = __import__('social_auth').__version__ 8 | 9 | LONG_DESCRIPTION = """ 10 | Django Social Auth is an easy to setup social authentication/registration 11 | mechanism for Django projects. 12 | 13 | Crafted using base code from django-twitter-oauth_ and django-openid-auth_, 14 | implements a common interface to define new authentication providers from 15 | third parties. 16 | """ 17 | 18 | 19 | def long_description(): 20 | """Return long description from README.rst if it's present 21 | because it doesn't get installed.""" 22 | try: 23 | return open(join(dirname(__file__), 'README.rst')).read() 24 | except IOError: 25 | return LONG_DESCRIPTION 26 | 27 | 28 | setup(name='django-social-auth', 29 | version=version, 30 | author='Matías Aguirre', 31 | author_email='matiasaguirre@gmail.com', 32 | description='Django social authentication made simple.', 33 | license='BSD', 34 | keywords='django, openid, oauth, social auth, application', 35 | url='https://github.com/omab/django-social-auth', 36 | packages=['social_auth', 37 | 'social_auth.backends', 38 | 'social_auth.backends.contrib', 39 | 'social_auth.backends.pipeline', 40 | 'social_auth.migrations'], 41 | package_data={'social_auth': ['locale/*/LC_MESSAGES/*']}, 42 | long_description=long_description(), 43 | install_requires=['Django>=1.2.5', 44 | 'python-social-auth>=0.1.12'], 45 | classifiers=['Framework :: Django', 46 | 'Development Status :: 4 - Beta', 47 | 'Topic :: Internet', 48 | 'License :: OSI Approved :: BSD License', 49 | 'Intended Audience :: Developers', 50 | 'Environment :: Web Environment', 51 | 'Programming Language :: Python :: 2.5', 52 | 'Programming Language :: Python :: 2.6', 53 | 'Programming Language :: Python :: 2.7'], 54 | zip_safe=False) 55 | -------------------------------------------------------------------------------- /social_auth/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django-social-auth application, allows OpenId or OAuth user 3 | registration/authentication just adding a few configurations. 4 | """ 5 | version = (0, 8, 1) 6 | __version__ = '.'.join(map(str, version)) 7 | -------------------------------------------------------------------------------- /social_auth/admin.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | 4 | MODELS = getattr(settings, 'SOCIAL_AUTH_MODELS', 5 | 'social_auth.db.django_models') 6 | 7 | 8 | if MODELS == 'social_auth.db.django_models': 9 | from social.apps.django_app.default import admin 10 | admin # placate pyflakes 11 | -------------------------------------------------------------------------------- /social_auth/backends/__init__.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | from social.backends.utils import load_backends, get_backend 4 | from social.backends.open_id import OpenIdAuth as OpenIDBackend 5 | 6 | 7 | def get_backends(force_load=False): 8 | return load_backends(getattr(settings, 'AUTHENTICATION_BACKENDS', []), 9 | force_load) 10 | 11 | 12 | # placate pyflakes 13 | OpenIDBackend 14 | get_backend 15 | -------------------------------------------------------------------------------- /social_auth/backends/amazon.py: -------------------------------------------------------------------------------- 1 | from social.backends.amazon import AmazonOAuth2 as AmazonBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/aol.py: -------------------------------------------------------------------------------- 1 | from social.backends.aol import AOLOpenId as AolBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/browserid.py: -------------------------------------------------------------------------------- 1 | from social.backends.persona import PersonaAuth as BrowserIDBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/__init__.py: -------------------------------------------------------------------------------- 1 | """Contrib auth modules""" 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/angel.py: -------------------------------------------------------------------------------- 1 | from social.backends.angel import AngelOAuth2 as AngelBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/appsfuel.py: -------------------------------------------------------------------------------- 1 | from social.backends.appsfuel import AppsfuelOAuth2 as AppsfuelBackend, \ 2 | AppsfuelOAuth2Sandbox as AppsfuelSandboxBackend 3 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/behance.py: -------------------------------------------------------------------------------- 1 | from social.backends.behance import BehanceOAuth2 as BehanceBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/belgiumeid.py: -------------------------------------------------------------------------------- 1 | from social.backends.belgiumeid import BelgiumEIDOpenId as EIDBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/bitbucket.py: -------------------------------------------------------------------------------- 1 | from social.backends.bitbucket import BitbucketOAuth as BitbucketBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/dailymotion.py: -------------------------------------------------------------------------------- 1 | from social.backends.dailymotion import DailymotionOAuth2 as DailymotionBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/disqus.py: -------------------------------------------------------------------------------- 1 | from social.backends.disqus import DisqusOAuth2 as DisqusBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/douban.py: -------------------------------------------------------------------------------- 1 | from social.backends.douban import DoubanOAuth as DoubanBackend, \ 2 | DoubanOAuth2 as Douban2Backend 3 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/dropbox.py: -------------------------------------------------------------------------------- 1 | from social.backends.dropbox import DropboxOAuth as DropboxBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/evernote.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | 4 | if getattr(settings, 'EVERNOTE_DEBUG', False): 5 | from social.backends.evernote import \ 6 | EvernoteSandboxOAuth as EvernoteBackend 7 | else: 8 | from social.backends.evernote import EvernoteOAuth as EvernoteBackend 9 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/exacttarget.py: -------------------------------------------------------------------------------- 1 | from social.backends.exacttarget import ExactTargetOAuth2 as ExactTargetBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/fedora.py: -------------------------------------------------------------------------------- 1 | from social.backends.fedora import FedoraOpenId as FedoraBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/fitbit.py: -------------------------------------------------------------------------------- 1 | from social.backends.fitbit import FitbitOAuth as FitbitBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/flickr.py: -------------------------------------------------------------------------------- 1 | from social.backends.flickr import FlickrOAuth as FlickrBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/foursquare.py: -------------------------------------------------------------------------------- 1 | from social.backends.foursquare import FoursquareOAuth2 as FoursquareBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/gae.py: -------------------------------------------------------------------------------- 1 | from social.backends.gae import GoogleAppEngineAuth as GAEBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/github.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | 4 | if getattr(settings, 'GITHUB_ORGANIZATION', None): 5 | from social.backends.github import \ 6 | GithubOrganizationOAuth2 as GithubBackend 7 | else: 8 | from social.backends.github import GithubOAuth2 as GithubBackend 9 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/instagram.py: -------------------------------------------------------------------------------- 1 | from social.backends.instagram import InstagramOAuth2 as InstagramBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/jawbone.py: -------------------------------------------------------------------------------- 1 | from social.backends.jawbone import JawboneOAuth2 as JawboneBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/linkedin.py: -------------------------------------------------------------------------------- 1 | from social.backends.linkedin import LinkedinOAuth as LinkedinBackend, \ 2 | LinkedinOAuth2 as LinkedinOAuth2Backend 3 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/live.py: -------------------------------------------------------------------------------- 1 | from social.backends.live import LiveOAuth2 as LiveBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/livejournal.py: -------------------------------------------------------------------------------- 1 | from social.backends.livejournal import LiveJournalOpenId as LiveJournalBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/mailru.py: -------------------------------------------------------------------------------- 1 | from social.backends.mailru import MailruOAuth2 as MailruBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/mendeley.py: -------------------------------------------------------------------------------- 1 | from social.backends.mendeley import MendeleyOAuth as MendeleyBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/mixcloud.py: -------------------------------------------------------------------------------- 1 | from social.backends.mixcloud import MixcloudOAuth2 as MixcloudBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/odnoklassniki.py: -------------------------------------------------------------------------------- 1 | from social.backends.odnoklassniki import \ 2 | OdnoklassnikiOAuth2 as OdnoklassnikiBackend, \ 3 | OdnoklassnikiApp as OdnoklassnikiAppBackend 4 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/orkut.py: -------------------------------------------------------------------------------- 1 | from social.backends.orkut import OrkutOAuth as OrkutBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/rdio.py: -------------------------------------------------------------------------------- 1 | from social.backends.rdio import RdioOAuth1 as RdioOAuth1Backend, \ 2 | RdioOAuth2 as RdioOAuth2Backend 3 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/readability.py: -------------------------------------------------------------------------------- 1 | from social.backends.readability import ReadabilityOAuth as ReadabilityBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/shopify.py: -------------------------------------------------------------------------------- 1 | from social.backends.shopify import ShopifyOAuth2 as ShopifyBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/skyrock.py: -------------------------------------------------------------------------------- 1 | from social.backends.skyrock import SkyrockOAuth as SkyrockBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/soundcloud.py: -------------------------------------------------------------------------------- 1 | from social.backends.soundcloud import SoundcloudOAuth2 as SoundcloudBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/stackoverflow.py: -------------------------------------------------------------------------------- 1 | from social.backends.stackoverflow import \ 2 | StackoverflowOAuth2 as StackoverflowBackend 3 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/stocktwits.py: -------------------------------------------------------------------------------- 1 | from social.backends.stocktwits import StocktwitsOAuth2 as StocktwitsBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/taobao.py: -------------------------------------------------------------------------------- 1 | from social.backends.taobao import TAOBAOAuth as TaobaoBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/trello.py: -------------------------------------------------------------------------------- 1 | from social.backends.trello import TrelloOAuth as TrelloBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/tripit.py: -------------------------------------------------------------------------------- 1 | from social.backends.tripit import TripItOAuth as TripItBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/tumblr.py: -------------------------------------------------------------------------------- 1 | from social.backends.tumblr import TumblrOAuth as TumblrBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/twilio.py: -------------------------------------------------------------------------------- 1 | from social.backends.twilio import TwilioAuth as TwilioBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/vk.py: -------------------------------------------------------------------------------- 1 | from social.backends.vk import VKontakteOpenAPI as VKOpenAPIBackend, \ 2 | VKOAuth2 as VKOAuth2Backend, \ 3 | VKAppOAuth2 as VKApplicationBackend 4 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/vkontakte.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | from social.backends.vk import VKontakteOpenAPI as VKOpenAPIBackend, \ 4 | VKOAuth2 as VKOAuth2Backend, \ 5 | VKAppOAuth2 as VKApplicationBackend 6 | 7 | warnings.warn('Vkontakte backend was renamed to vk backend, ' 8 | 'settings were renamed too. Please adjust your ' 9 | 'settings', DeprecationWarning) 10 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/weibo.py: -------------------------------------------------------------------------------- 1 | from social.backends.weibo import WeiboOAuth2 as WeiboBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/xing.py: -------------------------------------------------------------------------------- 1 | from social.backends.xing import XingOAuth as XingBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/yahoo.py: -------------------------------------------------------------------------------- 1 | from social.backends.yahoo import YahooOAuth as YahooOAuthBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/yammer.py: -------------------------------------------------------------------------------- 1 | from social.backends.yammer import YammerOAuth2 as YammerBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/yammer_staging.py: -------------------------------------------------------------------------------- 1 | from social.backends.yammer import YammerStagingOAuth2 as YammerStagingBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/contrib/yandex.py: -------------------------------------------------------------------------------- 1 | from social.backends.yandex import YandexOpenId as YandexBackend, \ 2 | YaruOAuth2 as YaruBackend, \ 3 | YandexOAuth2 as YandexOAuth2Backend 4 | -------------------------------------------------------------------------------- /social_auth/backends/facebook.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | 4 | if getattr(settings, 'FACEBOOK_APP_AUTH', False): 5 | from social.backends.facebook import \ 6 | FacebookAppOAuth2 as FacebookBackendBase 7 | else: 8 | from social.backends.facebook import FacebookOAuth2 as FacebookBackendBase 9 | 10 | 11 | REDIRECT_HTML = """ 12 | 20 | """ 21 | 22 | 23 | class FacebookBackend(FacebookBackendBase): 24 | def auth_html(self): 25 | key, secret = self.get_key_and_secret() 26 | namespace = self.setting('NAMESPACE', None) 27 | scope = self.get_scope() 28 | if scope: 29 | scope = self.SCOPE_SEPARATOR.join(scope) 30 | ctx = { 31 | 'FACEBOOK_APP_NAMESPACE': namespace or key, 32 | 'FACEBOOK_KEY': key, 33 | 'FACEBOOK_EXTENDED_PERMISSIONS': scope, 34 | 'FACEBOOK_COMPLETE_URI': self.redirect_uri, 35 | } 36 | tpl = self.setting('LOCAL_HTML', 'facebook.html') 37 | return self.strategy.render_html(tpl=tpl, html=REDIRECT_HTML, 38 | context=ctx) 39 | -------------------------------------------------------------------------------- /social_auth/backends/google.py: -------------------------------------------------------------------------------- 1 | from social.backends.google import GoogleOAuth2 as GoogleOAuth2Backend, \ 2 | GoogleOAuth as GoogleOAuthBackend, \ 3 | GoogleOpenId as GoogleBackend 4 | -------------------------------------------------------------------------------- /social_auth/backends/pipeline/__init__.py: -------------------------------------------------------------------------------- 1 | """Django-Social-Auth Pipeline. 2 | 3 | Pipelines must return a dictionary with values that will be passed as parameter 4 | to next pipeline item. Pipelines must take **kwargs parameters to avoid 5 | failure. At some point a pipeline entry must create a UserSocialAuth instance 6 | and load it to the output if the user logged in correctly. 7 | """ 8 | -------------------------------------------------------------------------------- /social_auth/backends/pipeline/associate.py: -------------------------------------------------------------------------------- 1 | from social.pipeline.social_auth import associate_by_email 2 | -------------------------------------------------------------------------------- /social_auth/backends/pipeline/misc.py: -------------------------------------------------------------------------------- 1 | from social.pipeline.partial import save_status_to_session 2 | save_status_to_session # placate pyflakes 3 | -------------------------------------------------------------------------------- /social_auth/backends/pipeline/sauth.py: -------------------------------------------------------------------------------- 1 | from social.pipeline.social_auth import social_user as social_auth_user, \ 2 | associate_user, load_extra_data 3 | social_auth_user, associate_user, load_extra_data # placate pyflakes 4 | -------------------------------------------------------------------------------- /social_auth/backends/pipeline/user.py: -------------------------------------------------------------------------------- 1 | from social.pipeline.user import get_username, create_user, \ 2 | user_details as update_user_details 3 | get_username, create_user, update_user_details # placate pyflakes 4 | -------------------------------------------------------------------------------- /social_auth/backends/reddit.py: -------------------------------------------------------------------------------- 1 | from social.backends.reddit import RedditOAuth2 as RedditBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/steam.py: -------------------------------------------------------------------------------- 1 | from social.backends.steam import SteamOpenId as SteamBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/stripe.py: -------------------------------------------------------------------------------- 1 | from social.backends.stripe import StripeOAuth2 as StripeBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/twitter.py: -------------------------------------------------------------------------------- 1 | from social.backends.twitter import TwitterOAuth as TwitterBackend 2 | -------------------------------------------------------------------------------- /social_auth/backends/yahoo.py: -------------------------------------------------------------------------------- 1 | from social.backends.yahoo import YahooOpenId as YahooBackend 2 | -------------------------------------------------------------------------------- /social_auth/context_processors.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | from social.apps.django_app.context_processors import login_redirect, \ 4 | backends, LazyDict 5 | from social.backends.oauth import BaseOAuth1, BaseOAuth2 6 | from social.backends.open_id import OpenIdAuth 7 | from social.utils import user_is_authenticated 8 | 9 | from social_auth.models import UserSocialAuth 10 | from social_auth.backends import get_backends 11 | 12 | # Note: social_auth_backends, social_auth_by_type_backends and 13 | # social_auth_by_name_backends don't play nice together. 14 | 15 | 16 | def social_auth_backends(request): 17 | """Load Social Auth current user data to context. 18 | Will add a output from backends_data to context under social_auth key. 19 | """ 20 | return {'social_auth': backends(request)} 21 | 22 | 23 | def social_auth_by_type_backends(request): 24 | """Load Social Auth current user data to context. 25 | Will add a output from backends_data to context under social_auth key where 26 | each entry will be grouped by backend type (openid, oauth, oauth2). 27 | """ 28 | def context_value(): 29 | data = dict(backends(request)['backends']) 30 | data['backends'] = group_backend_by_type(data['backends']) 31 | data['not_associated'] = group_backend_by_type(data['not_associated']) 32 | data['associated'] = group_backend_by_type(data['associated']) 33 | return data 34 | return {'social_auth': LazyDict(context_value)} 35 | 36 | 37 | def social_auth_by_name_backends(request): 38 | """Load Social Auth current user data to context. 39 | Will add a social_auth object whose attribute names are the names of each 40 | provider, e.g. social_auth.facebook would be the facebook association or 41 | None, depending on the logged in user's current associations. Providers 42 | with a hyphen have the hyphen replaced with an underscore, e.g. 43 | google-oauth2 becomes google_oauth2 when referenced in templates. 44 | """ 45 | def context_value(): 46 | keys = [key for key in get_backends().keys()] 47 | accounts = dict(zip(keys, [None] * len(keys))) 48 | user = request.user 49 | if user_is_authenticated(user): 50 | accounts.update((assoc.provider, assoc) 51 | for assoc in UserSocialAuth.get_social_auth_for_user(user)) 52 | return accounts 53 | return {'social_auth': LazyDict(context_value)} 54 | 55 | 56 | def social_auth_login_redirect(request): 57 | """Load current redirect to context.""" 58 | data = login_redirect(request) 59 | data['redirect_querystring'] = data.get('REDIRECT_QUERYSTRING') 60 | return data 61 | 62 | 63 | def group_backend_by_type(items): 64 | """Group items by backend type.""" 65 | result = defaultdict(list) 66 | backends_defined = get_backends() 67 | 68 | for item in items: 69 | name = getattr(item, 'provider', item) 70 | backend = backends_defined[name] 71 | if issubclass(backend, OpenIdAuth): 72 | result['openid'].append(item) 73 | elif issubclass(backend, BaseOAuth2): 74 | result['oauth2'].append(item) 75 | elif issubclass(backend, BaseOAuth1): 76 | result['oauth'].append(item) 77 | return dict(result) 78 | -------------------------------------------------------------------------------- /social_auth/exceptions.py: -------------------------------------------------------------------------------- 1 | from social.exceptions import * 2 | -------------------------------------------------------------------------------- /social_auth/fields.py: -------------------------------------------------------------------------------- 1 | from social.apps.django_app.default.fields import JSONField 2 | -------------------------------------------------------------------------------- /social_auth/locale/it/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omab/django-social-auth/699571a3b6d84aa2c25ffce59daa4c7f3559a0e4/social_auth/locale/it/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /social_auth/locale/it/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: PACKAGE VERSION\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2013-07-10 16:01+0200\n" 11 | "PO-Revision-Date: 2013-07-20 15:52+0100\n" 12 | "Last-Translator: ndr.michi@gmail.com \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=UTF-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 18 | "X-Generator: Poedit 1.5.7\n" 19 | "X-Poedit-Bookmarks: -1,5,-1,-1,-1,-1,-1,-1,-1,-1\n" 20 | 21 | #: exceptions.py:14 22 | #, python-format 23 | msgid "Incorrect authentication service \"%s\"" 24 | msgstr "Servizio di autenticazione non corretto \"%s\"" 25 | 26 | #: exceptions.py:42 27 | msgid "Authentication process was cancelled" 28 | msgstr "Il processo di autenticazione è stato annullato" 29 | 30 | #: exceptions.py:44 31 | #, python-format 32 | msgid "Authentication failed: %s" 33 | msgstr "Autenticazione non riuscita: %s" 34 | 35 | #: exceptions.py:51 36 | msgid "Authentication process canceled" 37 | msgstr "Processo di autenticazione annullato" 38 | 39 | #: exceptions.py:65 40 | #, python-format 41 | msgid "Token error: %s" 42 | msgstr "Errore con il Token: %s" 43 | 44 | #: backends/pipeline/social.py:17 45 | #, python-format 46 | msgid "This %(provider)s account is already in use." 47 | msgstr "Questo %(provider)s account è già in uso." 48 | -------------------------------------------------------------------------------- /social_auth/locale/pt_BR/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omab/django-social-auth/699571a3b6d84aa2c25ffce59daa4c7f3559a0e4/social_auth/locale/pt_BR/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /social_auth/locale/pt_BR/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # Luan Pablo , 2013. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: PACKAGE VERSION\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2013-07-24 17:26-0300\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: Luan Pablo \n" 13 | "Language-Team: LANGUAGE \n" 14 | "Language: \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" 19 | 20 | #: exceptions.py:14 21 | #, python-format 22 | msgid "Incorrect authentication service \"%s\"" 23 | msgstr "Serviço de autenticação incorreto: \"%s\"" 24 | 25 | #: exceptions.py:28 26 | msgid "Stop pipeline" 27 | msgstr "Interromper pipeline" 28 | 29 | #: exceptions.py:42 30 | msgid "Authentication process was cancelled" 31 | msgstr "O processo de autenticação foi cancelado" 32 | 33 | #: exceptions.py:44 34 | #, python-format 35 | msgid "Authentication failed: %s" 36 | msgstr "Falha na autenticação: %s" 37 | 38 | #: exceptions.py:51 39 | msgid "Authentication process canceled" 40 | msgstr "Processo de autenticação cancelado" 41 | 42 | #: exceptions.py:65 43 | #, python-format 44 | msgid "Token error: %s" 45 | msgstr "Erro de token: %s" 46 | 47 | #: exceptions.py:75 48 | #, python-format 49 | msgid "Missing needed parameter %s" 50 | msgstr "Parâmetro obrigatório %s não encontrado" 51 | 52 | #: exceptions.py:81 53 | msgid "Session value state missing." 54 | msgstr "Valor da sessão ausente." 55 | 56 | #: exceptions.py:87 57 | msgid "Wrong state parameter given." 58 | msgstr "Parâmetro inserido incorretamente." 59 | 60 | #: exceptions.py:98 61 | msgid "User revoke access to the token" 62 | msgstr "O usuário cancelou o acesso ao token" 63 | 64 | #: backends/pipeline/social.py:17 65 | #, python-format 66 | msgid "This %(provider)s account is already in use." 67 | msgstr "A conta %(provider)s já está em uso." 68 | -------------------------------------------------------------------------------- /social_auth/middleware.py: -------------------------------------------------------------------------------- 1 | from social.apps.django_app.middleware import SocialAuthExceptionMiddleware 2 | SocialAuthExceptionMiddleware # placate pyflakes 3 | -------------------------------------------------------------------------------- /social_auth/migrations/0002_auto__add_unique_nonce_timestamp_salt_server_url__add_unique_associati.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | from django.conf import settings 8 | from social_auth.utils import get_custom_user_model_for_migrations, \ 9 | custom_user_frozen_models 10 | 11 | 12 | USER_MODEL = get_custom_user_model_for_migrations() 13 | UID_LENGTH = getattr(settings, 'SOCIAL_AUTH_UID_LENGTH', 255) 14 | NONCE_SERVER_URL_LENGTH = getattr(settings, 'SOCIAL_AUTH_NONCE_SERVER_URL_LENGTH', 255) 15 | ASSOCIATION_SERVER_URL_LENGTH = getattr(settings, 'SOCIAL_AUTH_ASSOCIATION_SERVER_URL_LENGTH', 255) 16 | ASSOCIATION_HANDLE_LENGTH = getattr(settings, 'SOCIAL_AUTH_ASSOCIATION_HANDLE_LENGTH', 255) 17 | 18 | 19 | class Migration(SchemaMigration): 20 | 21 | def forwards(self, orm): 22 | # Adding index on 'Nonce', fields ['timestamp'] 23 | db.create_index('social_auth_nonce', ['timestamp']) 24 | 25 | # Adding unique constraint on 'Nonce', fields ['timestamp', 'salt', 'server_url'] 26 | db.create_unique('social_auth_nonce', ['timestamp', 'salt', 'server_url']) 27 | 28 | # Adding index on 'Association', fields ['issued'] 29 | db.create_index('social_auth_association', ['issued']) 30 | 31 | # Adding unique constraint on 'Association', fields ['handle', 'server_url'] 32 | db.create_unique('social_auth_association', ['handle', 'server_url']) 33 | 34 | 35 | def backwards(self, orm): 36 | # Removing unique constraint on 'Association', fields ['handle', 'server_url'] 37 | db.delete_unique('social_auth_association', ['handle', 'server_url']) 38 | 39 | # Removing index on 'Association', fields ['issued'] 40 | db.delete_index('social_auth_association', ['issued']) 41 | 42 | # Removing unique constraint on 'Nonce', fields ['timestamp', 'salt', 'server_url'] 43 | db.delete_unique('social_auth_nonce', ['timestamp', 'salt', 'server_url']) 44 | 45 | # Removing index on 'Nonce', fields ['timestamp'] 46 | db.delete_index('social_auth_nonce', ['timestamp']) 47 | 48 | 49 | models = { 50 | 'auth.group': { 51 | 'Meta': {'object_name': 'Group'}, 52 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 53 | 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), 54 | 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) 55 | }, 56 | 'auth.permission': { 57 | 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, 58 | 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), 59 | 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), 60 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 61 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) 62 | }, 63 | 'auth.user': { 64 | 'Meta': {'object_name': 'User'}, 65 | 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), 66 | 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), 67 | 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), 68 | 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), 69 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 70 | 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), 71 | 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 72 | 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 73 | 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), 74 | 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), 75 | 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 76 | 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), 77 | 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) 78 | }, 79 | 'contenttypes.contenttype': { 80 | 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, 81 | 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), 82 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 83 | 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), 84 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) 85 | }, 86 | 'social_auth.association': { 87 | 'Meta': {'unique_together': "(('server_url', 'handle'),)", 'object_name': 'Association'}, 88 | 'assoc_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 89 | 'handle': ('django.db.models.fields.CharField', [], {'max_length': str(ASSOCIATION_HANDLE_LENGTH)}), 90 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 91 | 'issued': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}), 92 | 'lifetime': ('django.db.models.fields.IntegerField', [], {}), 93 | 'secret': ('django.db.models.fields.CharField', [], {'max_length': '255'}), 94 | 'server_url': ('django.db.models.fields.CharField', [], {'max_length': str(ASSOCIATION_SERVER_URL_LENGTH)}) 95 | }, 96 | 'social_auth.nonce': { 97 | 'Meta': {'unique_together': "(('server_url', 'timestamp', 'salt'),)", 'object_name': 'Nonce'}, 98 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 99 | 'salt': ('django.db.models.fields.CharField', [], {'max_length': '40'}), 100 | 'server_url': ('django.db.models.fields.CharField', [], {'max_length': str(NONCE_SERVER_URL_LENGTH)}), 101 | 'timestamp': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}) 102 | }, 103 | 'social_auth.usersocialauth': { 104 | 'Meta': {'unique_together': "(('provider', 'uid'),)", 'object_name': 'UserSocialAuth'}, 105 | 'extra_data': ('social_auth.fields.JSONField', [], {'default': "'{}'"}), 106 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 107 | 'provider': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 108 | 'uid': ('django.db.models.fields.CharField', [], {'max_length': str(UID_LENGTH)}), 109 | 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'social_auth'", 'to': "orm['" + USER_MODEL + "']"}) 110 | } 111 | } 112 | models.update(custom_user_frozen_models(USER_MODEL)) 113 | complete_apps = ['social_auth'] 114 | -------------------------------------------------------------------------------- /social_auth/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omab/django-social-auth/699571a3b6d84aa2c25ffce59daa4c7f3559a0e4/social_auth/migrations/__init__.py -------------------------------------------------------------------------------- /social_auth/models.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | MODELS = getattr(settings, 'SOCIAL_AUTH_MODELS', 4 | 'social_auth.db.django_models') 5 | 6 | 7 | if MODELS == 'social_auth.db.django_models': 8 | from social.apps.django_app.default.models import \ 9 | UserSocialAuth as UserSocialAuthBase, \ 10 | Nonce as NonceBase, \ 11 | Association as AssociationBase, \ 12 | DjangoStorage as DjangoStorageBase 13 | else: 14 | from social.apps.django_app.me.models import \ 15 | UserSocialAuth as UserSocialAuthBase, \ 16 | Nonce as NonceBase, \ 17 | Association as AssociationBase, \ 18 | DjangoStorage as DjangoStorageBase 19 | 20 | 21 | class UserSocialAuth(UserSocialAuthBase): 22 | class Meta: 23 | proxy = True 24 | 25 | 26 | class Nonce(NonceBase): 27 | class Meta: 28 | proxy = True 29 | 30 | 31 | class Association(AssociationBase): 32 | class Meta: 33 | proxy = True 34 | 35 | 36 | class DjangoStorage(DjangoStorageBase): 37 | user = UserSocialAuth 38 | nonce = Nonce 39 | association = Association 40 | -------------------------------------------------------------------------------- /social_auth/strategy.py: -------------------------------------------------------------------------------- 1 | from social.strategies.django_strategy import DjangoStrategy 2 | 3 | 4 | class DSAStrategy(DjangoStrategy): 5 | settings_map = { 6 | 'AMAZON_SECRET': 'AMAZON_API_SECRET', 7 | 'AMAZON_KEY': 'AMAZON_APP_ID', 8 | 'AMAZON_SCOPE': 'AMAZON_EXTENDED_PERMISSIONS', 9 | 'ANGEL_KEY': 'ANGEL_CLIENT_ID', 10 | 'ANGEL_SECRET': 'ANGEL_CLIENT_SECRET', 11 | 'APPSFUEL_KEY': 'APPSFUEL_CLIENT_ID', 12 | 'APPSFUEL_SECRET': 'APPSFUEL_CLIENT_SECRET', 13 | 'BEHANCE_KEY': 'BEHANCE_CLIENT_ID', 14 | 'BEHANCE_SECRET': 'BEHANCE_CLIENT_SECRET', 15 | 'BEHANCE_SCOPE': 'BEHANCE_EXTENDED_PERMISSIONS', 16 | 'BITBUCKET_KEY': 'BITBUCKET_CONSUMER_KEY', 17 | 'BITBUCKET_SECRET': 'BITBUCKET_CONSUMER_SECRET', 18 | 'DAILYMOTION_KEY': 'DAILYMOTION_OAUTH2_KEY', 19 | 'DAILYMOTION_SECRET': 'DAILYMOTION_OAUTH2_SECRET', 20 | 'DISQUS_KEY': 'DISQUS_CLIENT_ID', 21 | 'DISQUS_SECRET': 'DISQUS_CLIENT_SECRET', 22 | 'DOUBAN_OAUTH2_KEY': 'DOUBAN2_CONSUMER_KEY', 23 | 'DOUBAN_OAUTH2_SECRET': 'DOUBAN2_CONSUMER_SECRET', 24 | 'DOUBAN_KEY': 'DOUBAN_CONSUMER_KEY', 25 | 'DOUBAN_SECRET': 'DOUBAN_CONSUMER_SECRET', 26 | 'DROPBOX_KEY': 'DROPBOX_API_SECRET', 27 | 'DROPBOX_SECRET': 'DROPBOX_APP_ID', 28 | 'EVERNOTE_KEY': 'EVERNOTE_CONSUMER_KEY', 29 | 'EVERNOTE_SECRET': 'EVERNOTE_CONSUMER_SECRET', 30 | 'EXACTTARGET_SECRET': 'EXACTTARGET_APP_SIGNATURE', 31 | 'EXACTTARGET_KEY': 'EXACTTARGET_UNUSED', 32 | 'FACEBOOK_KEY': 'FACEBOOK_APP_ID', 33 | 'FACEBOOK_SECRET': 'FACEBOOK_API_SECRET', 34 | 'FACEBOOK_SCOPE': 'FACEBOOK_EXTENDED_PERMISSIONS', 35 | 'FACEBOOK_APP_KEY': 'FACEBOOK_APP_ID', 36 | 'FACEBOOK_APP_LOCAL_HTML': 'FACEBOOK_LOCAL_HTML', 37 | 'FITBIT_KEY': 'FITBIT_CONSUMER_KEY', 38 | 'FITBIT_SECRET': 'FITBIT_CONSUMER_SECRET', 39 | 'FLICKR_SECRET': 'FLICKR_API_SECRET', 40 | 'FLICKR_KEY': 'FLICKR_APP_ID', 41 | 'FOURSQUARE_KEY': 'FOURSQUARE_CONSUMER_KEY', 42 | 'FOURSQUARE_SECRET': 'FOURSQUARE_CONSUMER_SECRET', 43 | 'GITHUB_SECRET': 'GITHUB_API_SECRET', 44 | 'GITHUB_KEY': 'GITHUB_APP_ID', 45 | 'GITHUB_SCOPE': 'GITHUB_EXTENDED_PERMISSIONS', 46 | 'GOOGLE_OAUTH_KEY': 'GOOGLE_CONSUMER_KEY', 47 | 'GOOGLE_OAUTH_SECRET': 'GOOGLE_CONSUMER_SECRET', 48 | 'GOOGLE_OAUTH_SCOPE': 'GOOGLE_OAUTH_EXTRA_SCOPE', 49 | 'GOOGLE_OAUTH2_KEY': 'GOOGLE_OAUTH2_CLIENT_KEY', 50 | 'GOOGLE_OAUTH2_SECRET': 'GOOGLE_OAUTH2_CLIENT_SECRET', 51 | 'GOOGLE_OAUTH2_SCOPE': 'GOOGLE_OAUTH_EXTRA_SCOPE', 52 | 'INSTAGRAM_KEY': 'INSTAGRAM_CLIENT_ID', 53 | 'INSTAGRAM_SECRET': 'INSTAGRAM_CLIENT_SECRET', 54 | 'JAWBONE_KEY': 'JAWBONE_CONSUMER_KEY', 55 | 'JAWBONE_SECRET': 'JAWBONE_CONSUMER_SECRET', 56 | 'JAWBONE_SCOPE': 'JAWBONE_EXTENDED_PERMISSIONS', 57 | 'LINKEDIN_KEY': 'LINKEDIN_CONSUMER_KEY', 58 | 'LINKEDIN_SECRET': 'LINKEDIN_CONSUMER_SECRET', 59 | 'LINKEDIN_FIELDS_SELECTORS': 'LINKEDIN_EXTRA_FIELD_SELECTORS', 60 | 'LINKEDIN_OAUTH2_KEY': 'LINKEDIN_CONSUMER_KEY', 61 | 'LINKEDIN_OAUTH2_SECRET': 'LINKEDIN_CONSUMER_SECRET', 62 | 'LINKEDIN_OAUTH2_FIELDS_SELECTORS': 'LINKEDIN_EXTRA_FIELD_SELECTORS', 63 | 'LINKEDIN_OAUTH2_SCOPE': 'LINKEDIN_SCOPE', 64 | 'LIVE_KEY': 'LIVE_CLIENT_ID', 65 | 'LIVE_SECRET': 'LIVE_CLIENT_SECRET', 66 | 'LIVE_SCOPE': 'LIVE_EXTENDED_PERMISSIONS', 67 | 'MAILRU_OAUTH2_KEY': 'MAILRU_OAUTH2_CLIENT_KEY', 68 | 'MAILRU_OAUTH2_SECRET': 'MAILRU_OAUTH2_CLIENT_SECRET', 69 | 'MAILRU_OAUTH2_SCOPE': 'MAILRU_OAUTH2_EXTRA_SCOPE', 70 | 'MENDELEY_KEY': 'MENDELEY_CONSUMER_KEY', 71 | 'MENDELEY_SECRET': 'MENDELEY_CONSUMER_SECRET', 72 | 'MIXCLOUD_KEY': 'MIXCLOUD_CLIENT_ID', 73 | 'MIXCLOUD_SECRET': 'MIXCLOUD_CLIENT_SECRET', 74 | 'ODNOKLASSNIKI_OAUTH2_KEY': 'ODNOKLASSNIKI_OAUTH2_CLIENT_KEY', 75 | 'ODNOKLASSNIKI_OAUTH2_SECRET': 'ODNOKLASSNIKI_OAUTH2_CLIENT_SECRET', 76 | 'ODNOKLASSNIKI_OAUTH2_SCOPE': 'ODNOKLASSNIKI_OAUTH2_EXTRA_SCOPE', 77 | 'ORKUT_KEY': 'ORKUT_CONSUMER_KEY', 78 | 'ORKUT_SECRET': 'ORKUT_CONSUMER_SECRET', 79 | 'RDIO_OAUTH2_SCOPE': 'RDIO2_PERMISSIONS', 80 | 'READABILITY_KEY': 'READABILITY_CONSUMER_KEY', 81 | 'READABILITY_SECRET': 'READABILITY_CONSUMER_SECRET', 82 | 'REDDIT_SECRET': 'REDDIT_API_SECRET', 83 | 'REDDIT_KEY': 'REDDIT_APP_ID', 84 | 'REDDIT_SCOPE': 'REDDIT_EXTENDED_PERMISSIONS', 85 | 'SHOPIFY_KEY': 'SHOPIFY_APP_API_KEY', 86 | 'SHOPIFY_SECRET': 'SHOPIFY_SHARED_SECRET', 87 | 'SKYROCK_KEY': 'SKYROCK_CONSUMER_KEY', 88 | 'SKYROCK_SECRET': 'SKYROCK_CONSUMER_SECRET', 89 | 'SOUNDCLOUD_KEY': 'SOUNDCLOUD_CLIENT_ID', 90 | 'SOUNDCLOUD_SECRET': 'SOUNDCLOUD_CLIENT_SECRET', 91 | 'SOUNDCLOUD_SCOPE': 'SOUNDCLOUD_EXTENDED_PERMISSIONS', 92 | 'STACKOVERFLOW_KEY': 'STACKOVERFLOW_CLIENT_ID', 93 | 'STACKOVERFLOW_SECRET': 'STACKOVERFLOW_CLIENT_SECRET', 94 | 'STACKOVERFLOW_SCOPE': 'STACKOVERFLOW_EXTENDED_PERMISSIONS', 95 | 'STOCKTWITS_KEY': 'STOCKTWITS_CONSUMER_KEY', 96 | 'STOCKTWITS_SECRET': 'STOCKTWITS_CONSUMER_SECRET', 97 | 'STRIPE_KEY': 'STRIPE_APP_ID', 98 | 'STRIPE_SECRET': 'STRIPE_APP_SECRET', 99 | 'TRELLO_KEY': 'TRELLO_CONSUMER_KEY', 100 | 'TRELLO_SECRET': 'TRELLO_CONSUMER_SECRET', 101 | 'TRIPIT_KEY': 'TRIPIT_API_KEY', 102 | 'TRIPIT_SECRET': 'TRIPIT_API_SECRET', 103 | 'TUMBLR_KEY': 'TUMBLR_CONSUMER_KEY', 104 | 'TUMBLR_SECRET': 'TUMBLR_CONSUMER_SECRET', 105 | 'TWILIO_SECRET': 'TWILIO_AUTH_TOKEN', 106 | 'TWILIO_KEY': 'TWILIO_CONNECT_KEY', 107 | 'TWITTER_KEY': 'TWITTER_CONSUMER_KEY', 108 | 'TWITTER_SECRET': 'TWITTER_CONSUMER_SECRET', 109 | 'VK_APP_SECRET': 'VKAPP_API_SECRET', 110 | 'VK_APP_KEY': 'VKAPP_APP_ID', 111 | 'VK_APP_USERMODE': 'VKAPP_USER_MODE', 112 | 'VK_OAUTH2_EXTRA_DATA': 'VK_EXTRA_DATA', 113 | 'VK_OAUTH2_SCOPE': 'VK_EXTRA_SCOPE', 114 | 'VK_OAUTH2_SECRET': 'VK_API_SECRET', 115 | 'VK_OPENAPI_LOCAL_HTML': 'VK_LOCAL_HTML', 116 | 'VK_OPENAPI_APP_ID': 'VK_APP_ID', 117 | 'WEIBO_KEY': 'WEIBO_CLIENT_KEY', 118 | 'WEIBO_SECRET': 'WEIBO_CLIENT_SECRET', 119 | 'XING_KEY': 'XING_CONSUMER_KEY', 120 | 'XING_SECRET': 'XING_CONSUMER_SECRET', 121 | 'YAHOO_KEY': 'YAHOO_CONSUMER_KEY', 122 | 'YAHOO_SECRET': 'YAHOO_CONSUMER_SECRET', 123 | 'YAMMER_KEY': 'YAMMER_CONSUMER_KEY', 124 | 'YAMMER_SECRET': 'YAMMER_CONSUMER_SECRET', 125 | 'YAMMER_STAGING_KEY': 'YAMMER_STAGING_CONSUMER_KEY', 126 | 'YAMMER_STAGING_SECRET': 'YAMMER_STAGING_CONSUMER_SECRET', 127 | 'YANDEX_SECRET': 'YANDEX_API_SECRET', 128 | 'YANDEX_KEY': 'YANDEX_APP_ID', 129 | 'ON_HTTPS': 'SOCIAL_AUTH_REDIRECT_IS_HTTPS', 130 | } 131 | 132 | def get_setting(self, name): 133 | if name in self.settings_map: 134 | # Try DSA setting name from map defined above 135 | try: 136 | return super(DSAStrategy, self).get_setting( 137 | self.settings_map[name] 138 | ) 139 | except (AttributeError, KeyError): 140 | pass 141 | # Fallback to PSA setting name 142 | return super(DSAStrategy, self).get_setting(name) 143 | 144 | def get_pipeline(self): 145 | pipeline = super(DSAStrategy, self).get_pipeline() 146 | pipeline_renamed = [] 147 | for entry in pipeline: 148 | if entry.startswith('social_auth.backends.pipeline.social'): 149 | entry = entry.replace( 150 | 'social_auth.backends.pipeline.social', 151 | 'social_auth.backends.pipeline.sauth' 152 | ) 153 | pipeline_renamed.append(entry) 154 | return pipeline_renamed 155 | -------------------------------------------------------------------------------- /social_auth/urls.py: -------------------------------------------------------------------------------- 1 | """URLs module""" 2 | try: 3 | from django.conf.urls import patterns, url 4 | except ImportError: 5 | # for Django version less then 1.4 6 | from django.conf.urls.defaults import patterns, url 7 | 8 | from social_auth.views import auth, complete, disconnect 9 | 10 | 11 | urlpatterns = patterns('', 12 | # authentication 13 | url(r'^login/(?P[^/]+)/$', auth, name='socialauth_begin'), 14 | url(r'^complete/(?P[^/]+)/$', complete, 15 | name='socialauth_complete'), 16 | 17 | # associate 18 | url(r'^associate/(?P[^/]+)/$', auth, 19 | name='socialauth_associate_begin'), 20 | url(r'^associate/complete/(?P[^/]+)/$', complete, 21 | name='socialauth_associate_complete'), 22 | 23 | # disconnection 24 | url(r'^disconnect/(?P[^/]+)/$', disconnect, 25 | name='socialauth_disconnect'), 26 | url(r'^disconnect/(?P[^/]+)/(?P[^/]+)/$', 27 | disconnect, name='socialauth_disconnect_individual'), 28 | ) 29 | -------------------------------------------------------------------------------- /social_auth/utils.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.db.models.loading import get_model 3 | 4 | 5 | def get_custom_user_model_for_migrations(): 6 | user_model = getattr(settings, 'SOCIAL_AUTH_USER_MODEL', None) or \ 7 | getattr(settings, 'AUTH_USER_MODEL', None) or \ 8 | 'auth.User' 9 | if user_model != 'auth.User': 10 | # In case of having a proxy model defined as USER_MODEL 11 | # We use auth.User instead to prevent migration errors 12 | # Since proxy models aren't present in migrations 13 | if get_model(*user_model.split('.'))._meta.proxy: 14 | user_model = 'auth.User' 15 | return user_model 16 | 17 | 18 | def custom_user_frozen_models(user_model): 19 | migration_name = getattr(settings, 'INITIAL_CUSTOM_USER_MIGRATION', 20 | '0001_initial.py') 21 | if user_model != 'auth.User': 22 | from south.migration.base import Migrations 23 | from south.exceptions import NoMigrations 24 | from south.creator.freezer import freeze_apps 25 | user_app, user_model = user_model.split('.') 26 | try: 27 | user_migrations = Migrations(user_app) 28 | except NoMigrations: 29 | extra_model = freeze_apps(user_app) 30 | else: 31 | initial_user_migration = user_migrations.migration(migration_name) 32 | extra_model = initial_user_migration.migration_class().models 33 | else: 34 | extra_model = {} 35 | return extra_model 36 | -------------------------------------------------------------------------------- /social_auth/views.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.contrib.auth import REDIRECT_FIELD_NAME 3 | from django.views.decorators.csrf import csrf_exempt, csrf_protect 4 | from django.contrib.auth.decorators import login_required 5 | from django.views.decorators.http import require_POST 6 | 7 | from social.utils import setting_name 8 | from social.actions import do_auth, do_complete, do_disconnect 9 | from social.strategies.utils import get_strategy 10 | from social.apps.django_app.utils import strategy, BACKENDS, STORAGE 11 | from social.apps.django_app.views import _do_login 12 | 13 | 14 | STRATEGY = getattr(settings, setting_name('STRATEGY'), 15 | 'social_auth.strategy.DSAStrategy') 16 | 17 | 18 | def load_strategy(*args, **kwargs): 19 | return get_strategy(BACKENDS, STRATEGY, STORAGE, *args, **kwargs) 20 | 21 | 22 | @strategy('socialauth_complete', load_strategy=load_strategy) 23 | def auth(request, backend): 24 | return do_auth(request.strategy, redirect_name=REDIRECT_FIELD_NAME) 25 | 26 | 27 | @csrf_exempt 28 | @strategy('socialauth_complete', load_strategy=load_strategy) 29 | def complete(request, backend, *args, **kwargs): 30 | return do_complete(request.strategy, _do_login, request.user, 31 | redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs) 32 | 33 | 34 | @login_required 35 | @strategy(load_strategy=load_strategy) 36 | @require_POST 37 | @csrf_protect 38 | def disconnect(request, backend, association_id=None): 39 | return do_disconnect(request.strategy, request.user, association_id, 40 | redirect_name=REDIRECT_FIELD_NAME) 41 | --------------------------------------------------------------------------------