From 88fd46ee69aca8f520a24d003dcec7140990e514 Mon Sep 17 00:00:00 2001 From: Ravi Kotecha Date: Sun, 12 Feb 2012 18:05:18 +0000 Subject: [PATCH] Add Instagram support --- .gitignore | 3 ++ README.rst | 27 ++++++++++++ example/settings.py | 1 + social_auth/backends/contrib/instagram.py | 54 +++++++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 social_auth/backends/contrib/instagram.py diff --git a/.gitignore b/.gitignore index bee6585..be0304f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ env/ doc/_build example/templates/script*.html contrib/tests/test_settings.py +*.ipr +*.iws +Django-social-auth.iml diff --git a/README.rst b/README.rst index 9f31fda..794faea 100644 --- a/README.rst +++ b/README.rst @@ -120,6 +120,7 @@ Configuration 'social_auth.backends.contrib.github.GithubBackend', 'social_auth.backends.contrib.dropbox.DropboxBackend', 'social_auth.backends.contrib.flickr.FlickrBackend', + 'social_auth.backends.contrib.instagram.InstagramBackend', 'social_auth.backends.OpenIDBackend', 'django.contrib.auth.backends.ModelBackend', ) @@ -158,6 +159,8 @@ Configuration DROPBOX_API_SECRET = '' FLICKR_APP_ID = '' FLICKR_API_SECRET = '' + INSTAGRAM_CLIENT_ID = '' + INSTAGRAM_CLIENT_SECRET = '' - Setup login URLs:: @@ -787,6 +790,24 @@ include in your document and the needed mechanism to trigger the POST to Check the second "Use Case" for an implementation example. +------- +Instagram +------- +Instagram uses OAuth v2 for Authentication + +- Register a new application at the `Instagram API`_, and + +- fill ``Client Id`` and ``Client Secret`` values in the settings:: + + INSTAGRAM_CLIENT_ID = '' + INSTAGRAM_CLIENT_SECRET = '' + +None: Instagram only allows one callback url so you'll have to change your urls.py to +accomodate both /complete and /associate routes, for example by having a single +/associate url which takes a ?complete=true parameter for the cases when you want +to complete rather than associate. + + ------- Testing ------- @@ -948,6 +969,10 @@ Attributions to whom deserves: - Flickr support - Provider name context processor +- r4vi_ (Ravi Kotecha) + + - Instagram support + ---------- Copyrights ---------- @@ -1010,6 +1035,7 @@ Base work is copyrighted by: .. _mattucf: https://github.com/mattucf .. _Quard: https://github.com/Quard .. _micrypt: https://github.com/micrypt +.. _r4vi: https://github.com/r4vi .. _South: http://south.aeracode.org/ .. _bedspax: https://github.com/bedspax .. _django-social-auth: https://github.com/omab/django-social-auth @@ -1028,3 +1054,4 @@ Base work is copyrighted by: .. _danielgtaylor: https://github.com/danielgtaylor .. _example application: https://github.com/omab/django-social-auth/blob/master/example/local_settings.py.template#L23 .. _BrowserID: https://browserid.org +.. _Instagram API: http://instagr.am/developer/ diff --git a/example/settings.py b/example/settings.py index 5bd8ad3..005ff2e 100644 --- a/example/settings.py +++ b/example/settings.py @@ -76,6 +76,7 @@ AUTHENTICATION_BACKENDS = ( 'social_auth.backends.yahoo.YahooBackend', 'social_auth.backends.contrib.linkedin.LinkedinBackend', 'social_auth.backends.contrib.flickr.FlickrBackend', + 'social_auth.backends.contrib.instagram.InstagramBackend', 'social_auth.backends.OpenIDBackend', 'social_auth.backends.contrib.livejournal.LiveJournalBackend', 'social_auth.backends.browserid.BrowserIDBackend', diff --git a/social_auth/backends/contrib/instagram.py b/social_auth/backends/contrib/instagram.py new file mode 100644 index 0000000..afdbafe --- /dev/null +++ b/social_auth/backends/contrib/instagram.py @@ -0,0 +1,54 @@ +import urllib + +from django.utils import simplejson + +from social_auth.backends import BaseOAuth2, OAuthBackend, USERNAME + + +INSTAGRAM_SERVER = 'instagram.com' +INSTAGRAM_AUTHORIZATION_URL = 'https://instagram.com/oauth/authorize' +INSTAGRAM_ACCESS_TOKEN_URL = 'https://instagram.com/oauth/access_token' +INSTAGRAM_CHECK_AUTH = 'https://api.instagram.com/v1/users/self' + + +class InstagramBackend(OAuthBackend): + name = 'instagram' + + def get_user_id(self, details, response): + return response['user']['id'] + + def get_user_details(self, response): + """Return user details from Instagram account""" + username = response['user']['username'] + fullname = response['user'].get('fullname', '') + email = response['user'].get('email', '') + + return {USERNAME: username, + 'first_name': fullname, + 'email': email + } + + +class InstagramAuth(BaseOAuth2): + """Instagram OAuth mechanism""" + AUTHORIZATION_URL = INSTAGRAM_AUTHORIZATION_URL + ACCESS_TOKEN_URL = INSTAGRAM_ACCESS_TOKEN_URL + SERVER_URL = INSTAGRAM_SERVER + AUTH_BACKEND = InstagramBackend + SETTINGS_KEY_NAME = 'INSTAGRAM_CLIENT_ID' + SETTINGS_SECRET_NAME = 'INSTAGRAM_CLIENT_SECRET' + + def user_data(self, access_token): + """Loads user data from service""" + params = {'access_token': access_token,} + url = INSTAGRAM_CHECK_AUTH + '?' + urllib.urlencode(params) + try: + return simplejson.load(urllib.urlopen(url)) + except ValueError: + return None + + +# Backend definition +BACKENDS = { + 'instagram': InstagramAuth, +} -- 2.39.5