--- /dev/null
+"""
+Odnoklassniki.ru OAuth2 support
+
+Take a look to http://dev.odnoklassniki.ru/wiki/display/ok/The+OAuth+2.0+Protocol
+
+You need to register OAuth application here:
+http://dev.odnoklassniki.ru/wiki/pages/viewpage.action?pageId=13992188
+
+Then setup your application according manual and use information from registration
+mail to set settings values
+
+"""
+
+from django.conf import settings
+from django.utils import simplejson
+
+from urllib import urlencode, unquote
+from urllib2 import Request, urlopen
+from hashlib import md5
+
+from social_auth.backends import OAuthBackend, BaseOAuth2, USERNAME
+
+ODNOKLASSNIKI_API_URL = 'http://api.odnoklassniki.ru/fb.do'
+ODNOKLASSNIKI_OAUTH2_SCOPE = [''] # Enough for authentication
+
+EXPIRES_NAME = getattr(settings, 'SOCIAL_AUTH_EXPIRATION', 'expires')
+
+class OdnoklassnikiBackend(OAuthBackend):
+ """Odnoklassniki authentication backend"""
+ name = 'odnoklassniki'
+ EXTRA_DATA = [('refresh_token', 'refresh_token'),
+ ('expires_in', EXPIRES_NAME)]
+
+ def get_user_id(self, details, response):
+ """Return user unique id provided by Odnoklassniki"""
+ return int(response['uid'])
+
+ def get_user_details(self, response):
+ """Return user details from Odnoklassniki request"""
+ values = { USERNAME: response['uid'], 'email': '', 'fullname': unquote(response['name']),
+ 'first_name': unquote(response['first_name']), 'last_name': unquote(response['last_name'])}
+ return values
+
+
+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'
+ SETTINGS_KEY_NAME = 'ODNOKLASSNIKI_OAUTH2_CLIENT_KEY'
+ SETTINGS_SECRET_NAME = 'ODNOKLASSNIKI_OAUTH2_CLIENT_SECRET'
+
+ def get_scope(self):
+ return ODNOKLASSNIKI_OAUTH2_SCOPE + getattr(settings, 'ODNOKLASSNIKI_OAUTH2_EXTRA_SCOPE', [])
+
+ def user_data(self, access_token):
+ """Return user data from Odnoklassniki REST API"""
+ data = {'access_token': access_token, 'method': 'users.getCurrentUser'}
+ return odnoklassniki_api(data)
+
+def odnoklassniki_sig(data):
+ """ Calculates signature of request data
+ access_token value must be included """
+
+ suffix = md5(data['access_token'] + settings.ODNOKLASSNIKI_OAUTH2_CLIENT_SECRET).hexdigest()
+
+ check_list = sorted(list(item + '=' + data[item] for item in data if item != 'access_token'))
+
+ return md5(''.join(check_list) + suffix).hexdigest()
+
+def odnoklassniki_api(data):
+ """ Calls Odnoklassniki REST API method
+ http://dev.odnoklassniki.ru/wiki/display/ok/Odnoklassniki+Rest+API
+ """
+ data.update({'application_key': settings.ODNOKLASSNIKI_OAUTH2_APP_KEY, 'format': 'JSON'})
+ data['sig'] = odnoklassniki_sig(data)
+
+ params = urlencode(data)
+ request = Request(ODNOKLASSNIKI_API_URL + '?' + params)
+ try:
+ return simplejson.loads(urlopen(request).read())
+ except (TypeError, KeyError, IOError, ValueError, IndexError):
+ return None
+
+# Backend definition
+BACKENDS = {
+ 'odnoklassniki': OdnoklassnikiOAuth2
+}
\ No newline at end of file