From aabb618bd9860024a2f4768ec06762878a6f92a8 Mon Sep 17 00:00:00 2001 From: Stas Kravets Date: Sat, 30 Apr 2011 11:12:47 +0400 Subject: [PATCH] Mail.ru OAuth 2.0 support added. --- example/local_settings.py.template | 3 + example/settings.py | 1 + example/templates/done.html | 5 +- example/templates/home.html | 1 + social_auth/backends/contrib/mailru.py | 88 +++++++++++++++++++ social_auth/backends/contrib/odnoklassniki.py | 2 +- 6 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 social_auth/backends/contrib/mailru.py diff --git a/example/local_settings.py.template b/example/local_settings.py.template index 0f8e6e8..b0583aa 100644 --- a/example/local_settings.py.template +++ b/example/local_settings.py.template @@ -18,5 +18,8 @@ VKONTAKTE_APP_SECRET = '' ODNOKLASSNIKI_OAUTH2_CLIENT_KEY = '' ODNOKLASSNIKI_OAUTH2_APP_KEY = '' ODNOKLASSNIKI_OAUTH2_CLIENT_SECRET = '' +MAILRU_OAUTH2_CLIENT_KEY = '' +MAILRU_OAUTH2_APP_KEY = '' +MAILRU_OAUTH2_CLIENT_SECRET = '' #SOCIAL_AUTH_USER_MODEL = 'app.CustomUser' SOCIAL_AUTH_ERROR_KEY = 'socialauth_error' diff --git a/example/settings.py b/example/settings.py index 06d3e89..7483d28 100644 --- a/example/settings.py +++ b/example/settings.py @@ -75,6 +75,7 @@ AUTHENTICATION_BACKENDS = ( 'social_auth.backends.contrib.yandex.YandexBackend', 'social_auth.backends.contrib.odnoklassniki.OdnoklassnikiBackend', 'social_auth.backends.contrib.vkontakte.VKontakteOAuth2Backend', + 'social_auth.backends.contrib.mailru.MailruBackend', 'django.contrib.auth.backends.ModelBackend', ) diff --git a/example/templates/done.html b/example/templates/done.html index cc84635..b0f9e70 100644 --- a/example/templates/done.html +++ b/example/templates/done.html @@ -48,7 +48,8 @@ {% if odnoklassniki %}(disconnect){% endif %}
  • VKontakte OAuth 2.0
  • {% if vkontakte_oauth2 %}(disconnect){% endif %} - +
  • Mail.ru OAuth 2.0
  • + {% if mailru_oauth2 %}(disconnect){% endif %} @@ -74,7 +75,7 @@
  • -
    {% csrf_token %} + {% csrf_token %}
    diff --git a/social_auth/backends/contrib/mailru.py b/social_auth/backends/contrib/mailru.py new file mode 100644 index 0000000..583c01a --- /dev/null +++ b/social_auth/backends/contrib/mailru.py @@ -0,0 +1,88 @@ +""" +Mail.ru OAuth2 support + +Take a look to http://api.mail.ru/docs/guides/oauth/ + +You need to register OAuth site here: +http://api.mail.ru/sites/my/add + +Then update your settings values using registration information + +""" + +from django.conf import settings +from django.utils import simplejson + +from urllib import urlencode, unquote +from urllib2 import Request, urlopen, HTTPError +from hashlib import md5 + +from social_auth.backends import OAuthBackend, BaseOAuth2, USERNAME + +MAILRU_API_URL = 'http://www.appsmail.ru/platform/api' +MAILRU_OAUTH2_SCOPE = [''] + +EXPIRES_NAME = getattr(settings, 'SOCIAL_AUTH_EXPIRATION', 'expires') + +class MailruBackend(OAuthBackend): + """Mail.ru authentication backend""" + name = 'mailru-oauth2' + EXTRA_DATA = [('refresh_token', 'refresh_token'), + ('expires_in', EXPIRES_NAME)] + + def get_user_id(self, details, response): + """Return user unique id provided by Mail.ru""" + return int(response['uid']) + + def get_user_details(self, response): + """Return user details from Mail.ru request""" + values = { USERNAME: unquote(response['nick']), 'email': unquote(response['email']), + 'first_name': unquote(response['first_name']), 'last_name': unquote(response['last_name'])} + + if values['first_name'] and values['last_name']: + values['fullname'] = "%s %s" % (values['first_name'], values['last_name']) + return values + + +class MailruOAuth2(BaseOAuth2): + """Mail.ru OAuth2 support""" + AUTH_BACKEND = MailruBackend + AUTHORIZATION_URL = 'https://connect.mail.ru/oauth/authorize' + ACCESS_TOKEN_URL = 'https://connect.mail.ru/oauth/token' + SETTINGS_KEY_NAME = 'MAILRU_OAUTH2_CLIENT_KEY' + SETTINGS_SECRET_NAME = 'MAILRU_OAUTH2_CLIENT_SECRET' + + def get_scope(self): + return MAILRU_OAUTH2_SCOPE + getattr(settings, 'MAILRU_OAUTH2_EXTRA_SCOPE', []) + + def user_data(self, access_token): + """Return user data from Mail.ru REST API""" + data = {'method': 'users.getInfo', 'session_key': access_token} + return mailru_api(data)[0] + +def mailru_sig(data): + """ Calculates signature of request data """ + + param_list = sorted(list(item + '=' + data[item] for item in data)) + + return md5(''.join(param_list) + settings.MAILRU_OAUTH2_CLIENT_SECRET).hexdigest() + +def mailru_api(data): + """ Calls Mail.ru REST API method + http://api.mail.ru/docs/guides/restapi/ + """ + data.update({'app_id': settings.MAILRU_OAUTH2_CLIENT_KEY, 'secure': '1'}) + data['sig'] = mailru_sig(data) + + params = urlencode(data) + request = Request(MAILRU_API_URL, params) + try: + return simplejson.loads(urlopen(request).read()) + except (TypeError, KeyError, IOError, ValueError, IndexError): + return None + + +# Backend definition +BACKENDS = { + 'mailru-oauth2': MailruOAuth2 +} \ No newline at end of file diff --git a/social_auth/backends/contrib/odnoklassniki.py b/social_auth/backends/contrib/odnoklassniki.py index d05d64d..ad57701 100644 --- a/social_auth/backends/contrib/odnoklassniki.py +++ b/social_auth/backends/contrib/odnoklassniki.py @@ -46,7 +46,7 @@ class OdnoklassnikiOAuth2(BaseOAuth2): """Odnoklassniki OAuth2 support""" AUTH_BACKEND = OdnoklassnikiBackend AUTHORIZATION_URL = 'http://www.odnoklassniki.ru/oauth/authorize' - ACCESS_TOKEN_URL = ' http://api.odnoklassniki.ru/oauth/token.do' + ACCESS_TOKEN_URL = 'http://api.odnoklassniki.ru/oauth/token.do' SETTINGS_KEY_NAME = 'ODNOKLASSNIKI_OAUTH2_CLIENT_KEY' SETTINGS_SECRET_NAME = 'ODNOKLASSNIKI_OAUTH2_CLIENT_SECRET' -- 2.39.5