diff --git a/docs/backends/edmodo.rst b/docs/backends/edmodo.rst new file mode 100644 index 000000000..095c45627 --- /dev/null +++ b/docs/backends/edmodo.rst @@ -0,0 +1,22 @@ +Edmodo +====== + +Edmodo supports OAuth 2. + +- Register a new application at `Edmodo Connect API`_, and follow the + instructions below. +- Add the Edmodo OAuth2 backend to your settings page:: + + SOCIAL_AUTH_AUTHENTICATION_BACKENDS = ( + ... + 'social.backends.edmodo.EdmodoOAuth2', + ... + ) + +- Fill ``App Key``, ``App Secret`` and ``App Scope`` values in the settings:: + + SOCIAL_AUTH_EDMODO_OAUTH2_KEY = '' + SOCIAL_AUTH_EDMODO_OAUTH2_SECRET = '' + SOCIAL_AUTH_EDMODO_SCOPE = ['basic'] + +.. _Edmodo Connect API: https://developers.edmodo.com/edmodo-connect/edmodo-connect-overview-getting-started/ diff --git a/docs/backends/index.rst b/docs/backends/index.rst index 7e3a23541..797bd6c41 100644 --- a/docs/backends/index.rst +++ b/docs/backends/index.rst @@ -71,6 +71,7 @@ Social backends dribbble drip dropbox + edmodo eveonline evernote facebook diff --git a/docs/thanks.rst b/docs/thanks.rst index ca4a40e68..46d7a2078 100644 --- a/docs/thanks.rst +++ b/docs/thanks.rst @@ -110,6 +110,7 @@ let me know and I'll update the list): * vbsteven_ * sbassi_ * aspcanada_ + * browniebroke_ .. _python-social-auth: https://github.com/omab/python-social-auth @@ -215,3 +216,4 @@ let me know and I'll update the list): .. _vbsteven: https://github.com/vbsteven .. _sbassi: https://github.com/sbassi .. _aspcanada: https://github.com/aspcanada +.. _browniebroke: https://github.com/browniebroke diff --git a/social/backends/edmodo.py b/social/backends/edmodo.py new file mode 100644 index 000000000..cc735897d --- /dev/null +++ b/social/backends/edmodo.py @@ -0,0 +1,34 @@ +""" +Edmodo OAuth2 Sign-in backend, docs at: + http://psa.matiasaguirre.net/docs/backends/edmodo.html +""" +from social.backends.oauth import BaseOAuth2 + + +class EdmodoOAuth2(BaseOAuth2): + """Edmodo OAuth2""" + name = 'edmodo' + AUTHORIZATION_URL = 'https://api.edmodo.com/oauth/authorize' + ACCESS_TOKEN_URL = 'https://api.edmodo.com/oauth/token' + ACCESS_TOKEN_METHOD = 'POST' + + def get_user_details(self, response): + """Return user details from Edmodo account""" + fullname, first_name, last_name = self.get_user_names( + first_name=response.get('first_name'), + last_name=response.get('last_name') + ) + return { + 'username': response.get('username'), + 'email': response.get('email'), + 'fullname': fullname, + 'first_name': first_name, + 'last_name': last_name + } + + def user_data(self, access_token, *args, **kwargs): + """Loads user data from Edmodo""" + return self.get_json( + 'https://api.edmodo.com/users/me', + params={'access_token': access_token} + ) diff --git a/social/tests/backends/test_edmodo.py b/social/tests/backends/test_edmodo.py new file mode 100644 index 000000000..ff3914c1d --- /dev/null +++ b/social/tests/backends/test_edmodo.py @@ -0,0 +1,44 @@ +import json + +from social.tests.backends.oauth import OAuth2Test + + +class EdmodoOAuth2Test(OAuth2Test): + backend_path = 'social.backends.edmodo.EdmodoOAuth2' + user_data_url = 'https://api.edmodo.com/users/me' + expected_username = 'foobar12345' + access_token_body = json.dumps({ + 'access_token': 'foobar', + 'token_type': 'bearer' + }) + user_data_body = json.dumps({ + 'username': 'foobar12345', + 'coppa_verified': False, + 'first_name': 'Foo', + 'last_name': 'Bar', + 'premium': False, + 'verified_institution_member': False, + 'url': 'https://api.edmodo.com/users/12345', + 'type': 'teacher', + 'time_zone': None, + 'end_level': None, + 'start_level': None, + 'locale': 'en', + 'subjects': None, + 'utc_offset': None, + 'email': 'foo.bar@example.com', + 'gender': None, + 'about': None, + 'user_title': None, + 'id': 12345, + 'avatars': { + 'small': 'https://api.edmodo.com/users/12345/avatar?type=small&u=5a15xug93m53mi4ey3ck4fvkq', + 'large': 'https://api.edmodo.com/users/12345/avatar?type=large&u=5a15xug93m53mi4ey3ck4fvkq' + } + }) + + def test_login(self): + self.do_login() + + def test_partial_pipeline(self): + self.do_partial_pipeline()