Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions common/djangoapps/third_party_auth/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import json
import logging
from social.backends.base import BaseAuth
from social.backends.oauth import BaseOAuth2
from social.backends.oauth import OAuthAuth
from social.backends.saml import SAMLAuth, SAMLIdentityProvider
from social.exceptions import SocialAuthBaseException
from social.utils import module_member
Expand All @@ -30,7 +30,7 @@ def _load_backend_classes(base_class=BaseAuth):
if issubclass(auth_class, base_class):
yield auth_class
_PSA_BACKENDS = {backend_class.name: backend_class for backend_class in _load_backend_classes()}
_PSA_OAUTH2_BACKENDS = [backend_class.name for backend_class in _load_backend_classes(BaseOAuth2)]
_PSA_OAUTH2_BACKENDS = [backend_class.name for backend_class in _load_backend_classes(OAuthAuth)]
_PSA_SAML_BACKENDS = [backend_class.name for backend_class in _load_backend_classes(SAMLAuth)]


Expand Down Expand Up @@ -166,6 +166,7 @@ def get_authentication_backend(self):
class OAuth2ProviderConfig(ProviderConfig):
"""
Configuration Entry for an OAuth2 based provider.
Also works for OAuth1 providers.
"""
prefix = 'oa2'
KEY_FIELDS = ('backend_name', ) # Backend name is unique
Expand All @@ -191,7 +192,7 @@ class OAuth2ProviderConfig(ProviderConfig):
other_settings = models.TextField(blank=True, help_text="Optional JSON object with advanced settings, if any.")

class Meta(object): # pylint: disable=missing-docstring
verbose_name = "Provider Configuration (OAuth2)"
verbose_name = "Provider Configuration (OAuth)"
verbose_name_plural = verbose_name

def clean(self):
Expand Down
6 changes: 3 additions & 3 deletions common/djangoapps/third_party_auth/strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
ConfigurationModels rather than django.settings
"""
from .models import OAuth2ProviderConfig
from social.backends.oauth import BaseOAuth2
from social.backends.oauth import OAuthAuth
from social.strategies.django_strategy import DjangoStrategy


Expand All @@ -17,11 +17,11 @@ def setting(self, name, default=None, backend=None):
Load the setting from a ConfigurationModel if possible, or fall back to the normal
Django settings lookup.

BaseOAuth2 subclasses will call this method for every setting they want to look up.
OAuthAuth subclasses will call this method for every setting they want to look up.
SAMLAuthBackend subclasses will call this method only after first checking if the
setting 'name' is configured via SAMLProviderConfig.
"""
if isinstance(backend, BaseOAuth2):
if isinstance(backend, OAuthAuth):
provider_config = OAuth2ProviderConfig.current(backend.name)
if not provider_config.enabled:
raise Exception("Can't fetch setting of a disabled backend/provider.")
Expand Down
45 changes: 45 additions & 0 deletions common/djangoapps/third_party_auth/tests/specs/test_twitter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""
Separate integration test for Twitter which is an OAuth1 provider.
"""

from mock import patch
from third_party_auth.tests.specs import base


class TwitterIntegrationTest(base.Oauth2IntegrationTest):
"""Integration tests for Twitter backend."""

def setUp(self):
super(TwitterIntegrationTest, self).setUp()
self.provider = self.configure_twitter_provider(
enabled=True,
key='twitter_oauth1_key',
secret='twitter_oauth1_secret',
)

# To test an OAuth1 provider, we need to patch an additional method:
patcher = patch(
'social.backends.twitter.TwitterOAuth.unauthorized_token',
create=True,
return_value="unauth_token"
)
patcher.start()
self.addCleanup(patcher.stop)

TOKEN_RESPONSE_DATA = {
'access_token': 'access_token_value',
'token_type': 'bearer',
}
USER_RESPONSE_DATA = {
'id': 10101010,
'name': 'Bob Loblaw',
'description': 'A Twitter User',
'screen_name': 'bobloblaw',
'location': 'Twitterverse',
'followers_count': 77,
'verified': False,
}

def get_username(self):
response_data = self.get_response_data()
return response_data.get('screen_name')
10 changes: 10 additions & 0 deletions common/djangoapps/third_party_auth/tests/testutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ def configure_linkedin_provider(cls, **kwargs):
kwargs.setdefault("secret", "test")
return cls.configure_oauth_provider(**kwargs)

@classmethod
def configure_twitter_provider(cls, **kwargs):
""" Update the settings for the Twitter third party auth provider/backend """
kwargs.setdefault("name", "Twitter")
kwargs.setdefault("backend_name", "twitter")
kwargs.setdefault("icon_class", "fa-twitter")
kwargs.setdefault("key", "test")
kwargs.setdefault("secret", "test")
return cls.configure_oauth_provider(**kwargs)


class TestCase(ThirdPartyAuthTestMixin, django.test.TestCase):
"""Base class for auth test cases."""
Expand Down
1 change: 1 addition & 0 deletions lms/envs/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@
'social.backends.google.GoogleOAuth2',
'social.backends.linkedin.LinkedinOAuth2',
'social.backends.facebook.FacebookOAuth2',
'social.backends.twitter.TwitterOAuth',
'third_party_auth.dummy.DummyBackend',
'third_party_auth.saml.SAMLAuthBackend',
) + AUTHENTICATION_BACKENDS
Expand Down