Skip to content

Commit

Permalink
Merge 37e78b8 into 1091932
Browse files Browse the repository at this point in the history
  • Loading branch information
st4lk committed Feb 9, 2020
2 parents 1091932 + 37e78b8 commit 2973975
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 89 deletions.
4 changes: 3 additions & 1 deletion Makefile
Expand Up @@ -66,9 +66,11 @@ native-run-example: native-migrate
native-clean:
find . -path ./venv -prune | grep -E "(__pycache__|\.pyc|\.pyo$$)" | xargs rm -rf

native-test: native-install-all native-clean native-lint
native-test-only: native-install-all native-clean
PYTHONPATH='example_project/' python -m pytest -Wignore $(TEST_ARGS)

native-test: native-lint native-test-only

native-lint: native-install-all
flake8 .

Expand Down
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Expand Up @@ -4,6 +4,7 @@ rest_social_auth release notes
master
------
- Update supported version of django-rest-knox (>=4.0.0, <5.0.0). v4 has breaking changes.
- Allow to use token auth with OAuth1 without django session enabled

Issues: #110

Expand Down
33 changes: 22 additions & 11 deletions rest_social_auth/views.py
Expand Up @@ -166,21 +166,32 @@ def get_object(self):
self.request.backend.STATE_PARAMETER = False

if self.oauth_v1():
# Oauth1 uses sessions, in case of token authentication session store will be empty
backend = self.request.backend
session_token_name = backend.name + backend.UNATHORIZED_TOKEN_SUFIX
if not self.request.session.exists(session_token_name):
oauth1_tokrn_param = backend.data.get(backend.OAUTH_TOKEN_PARAMETER_NAME)
self.request.session[session_token_name] = [
urlencode({
backend.OAUTH_TOKEN_PARAMETER_NAME: oauth1_tokrn_param,
'oauth_token_secret': backend.data.get('oauth_token_secret')
})
]
self.save_token_param_in_session()

user = self.request.backend.complete(user=user)
return user

def save_token_param_in_session(self):
"""
Save token param in strategy's session.
This method will allow to use token auth with OAuth1 even if session is not enabled in
django settings (social_core expects that session is enabled).
"""
backend = self.request.backend
session_token_name = backend.name + backend.UNATHORIZED_TOKEN_SUFIX
session = self.request.strategy.session
if (
(isinstance(session, dict) and session_token_name not in session) or
not session.exists(session_token_name)
):
oauth1_token_param = backend.data.get(backend.OAUTH_TOKEN_PARAMETER_NAME)
session[session_token_name] = [
urlencode({
backend.OAUTH_TOKEN_PARAMETER_NAME: oauth1_token_param,
'oauth_token_secret': backend.data.get('oauth_token_secret')
})
]

def do_login(self, backend, user):
"""
Do login action here.
Expand Down
36 changes: 12 additions & 24 deletions tests/test_jwt.py
@@ -1,4 +1,4 @@
from django.test import modify_settings
from django.test import override_settings
from django.urls import reverse
from rest_framework.test import APITestCase
from rest_framework_jwt.settings import api_settings as jwt_api_settings
Expand All @@ -7,33 +7,22 @@
from .base import BaseFacebookAPITestCase, BaseTwitterApiTestCase


jwt_modify_settings = dict(
INSTALLED_APPS={
'remove': [
'django.contrib.sessions',
'rest_framework.authtoken',
'knox',
]
},
MIDDLEWARE_CLASSES={
'remove': [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
],
}
jwt_override_settings = dict(
INSTALLED_APPS=[
'django.contrib.contenttypes',
'rest_framework',
'social_django',
'rest_social_auth',
'users',
],
MIDDLEWARE=[],
)


@override_settings(**jwt_override_settings)
class TestSocialAuth1JWT(APITestCase, BaseTwitterApiTestCase):

@modify_settings(INSTALLED_APPS={'remove': ['rest_framework.authtoken', ]})
def test_login_social_oauth1_jwt(self):
"""
Currently oauth1 works only if session is enabled.
Probably it is possible to make it work without session, but
it will be needed to change the logic in python-social-auth.
"""
resp = self.client.post(
reverse('login_social_jwt_user'), data={'provider': 'twitter'})
self.assertEqual(resp.status_code, 200)
Expand All @@ -46,9 +35,9 @@ def test_login_social_oauth1_jwt(self):
self.assertEqual(resp.status_code, 200)


@override_settings(**jwt_override_settings)
class TestSocialAuth2JWT(APITestCase, BaseFacebookAPITestCase):

@modify_settings(**jwt_modify_settings)
def _check_login_social_jwt_only(self, url, data):
jwt_decode_handler = jwt_api_settings.JWT_DECODE_HANDLER
resp = self.client.post(url, data)
Expand All @@ -57,7 +46,6 @@ def _check_login_social_jwt_only(self, url, data):
jwt_data = jwt_decode_handler(resp.data['token'])
self.assertEqual(jwt_data['email'], self.email)

@modify_settings(**jwt_modify_settings)
def _check_login_social_jwt_user(self, url, data):
jwt_decode_handler = jwt_api_settings.JWT_DECODE_HANDLER
resp = self.client.post(url, data)
Expand Down
22 changes: 17 additions & 5 deletions tests/test_knox.py
@@ -1,3 +1,4 @@
from django.test import override_settings
from django.urls import reverse
from knox.auth import TokenAuthentication as KnoxTokenAuthentication
from rest_framework.test import APITestCase
Expand All @@ -6,14 +7,24 @@
from .base import BaseFacebookAPITestCase, BaseTwitterApiTestCase


knox_override_settings = dict(
INSTALLED_APPS=[
'django.contrib.contenttypes',
'rest_framework',
'social_django',
'rest_social_auth',
'knox', # For django-rest-knox
'users',
],
MIDDLEWARE=[
],
)


@override_settings(**knox_override_settings)
class TestSocialAuth1Knox(APITestCase, BaseTwitterApiTestCase):

def test_login_social_oauth1_knox(self):
"""
Currently oauth1 works only if session is enabled.
Probably it is possible to make it work without session, but
it will be needed to change the logic in python-social-auth.
"""
resp = self.client.post(
reverse('login_social_knox_user'), data={'provider': 'twitter'})
self.assertEqual(resp.status_code, 200)
Expand All @@ -26,6 +37,7 @@ def test_login_social_oauth1_knox(self):
self.assertEqual(resp.status_code, 200)


@override_settings(**knox_override_settings)
class TestSocialAuth2Knox(APITestCase, BaseFacebookAPITestCase):

def _check_login_social_knox_only(self, url, data):
Expand Down
36 changes: 12 additions & 24 deletions tests/test_simple_jwt.py
@@ -1,4 +1,4 @@
from django.test import modify_settings
from django.test import override_settings
from django.urls import reverse
from rest_framework.test import APITestCase
from rest_framework_simplejwt.authentication import JWTAuthentication
Expand All @@ -7,33 +7,22 @@
from .base import BaseFacebookAPITestCase, BaseTwitterApiTestCase


jwt_simple_modify_settings = dict(
INSTALLED_APPS={
'remove': [
'django.contrib.sessions',
'rest_framework.authtoken',
'knox',
]
},
MIDDLEWARE_CLASSES={
'remove': [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
],
}
jwt_simple_override_settings = dict(
INSTALLED_APPS=[
'django.contrib.contenttypes',
'rest_framework',
'social_django',
'rest_social_auth',
'users',
],
MIDDLEWARE=[],
)


@override_settings(**jwt_simple_override_settings)
class TestSocialAuth1SimpleJWT(APITestCase, BaseTwitterApiTestCase):

@modify_settings(INSTALLED_APPS={'remove': ['rest_framework.authtoken', ]})
def test_login_social_oauth1_jwt(self):
"""
Currently oauth1 works only if session is enabled.
Probably it is possible to make it work without session, but
it will be needed to change the logic in python-social-auth.
"""
resp = self.client.post(
reverse('login_social_jwt_user'), data={'provider': 'twitter'})
self.assertEqual(resp.status_code, 200)
Expand All @@ -46,9 +35,9 @@ def test_login_social_oauth1_jwt(self):
self.assertEqual(resp.status_code, 200)


@override_settings(**jwt_simple_override_settings)
class TestSocialAuth2SimpleJWT(APITestCase, BaseFacebookAPITestCase):

@modify_settings(**jwt_simple_modify_settings)
def _check_login_social_simple_jwt_only(self, url, data, token_type):
resp = self.client.post(url, data)
self.assertEqual(resp.status_code, 200)
Expand All @@ -57,7 +46,6 @@ def _check_login_social_simple_jwt_only(self, url, data, token_type):
token_instance = jwt_auth.get_validated_token(resp.data['token'])
self.assertEqual(token_instance['token_type'], token_type)

@modify_settings(**jwt_simple_modify_settings)
def _check_login_social_simple_jwt_user(self, url, data, token_type):
resp = self.client.post(url, data)
self.assertEqual(resp.status_code, 200)
Expand Down
39 changes: 15 additions & 24 deletions tests/test_token.py
@@ -1,6 +1,6 @@
import json

from django.test import modify_settings
from django.test import override_settings
from django.urls import reverse
from rest_framework.authtoken.models import Token
from rest_framework.test import APITestCase
Expand All @@ -9,33 +9,25 @@
from .base import BaseFacebookAPITestCase, BaseTwitterApiTestCase


token_modify_settings = dict(
INSTALLED_APPS={
'remove': [
'django.contrib.sessions',
'knox',
]
},
MIDDLEWARE_CLASSES={
'remove': [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
],
}
token_override_settings = dict(
INSTALLED_APPS=[
'django.contrib.contenttypes',
'rest_framework',
'rest_framework.authtoken',
'social_django',
'rest_social_auth',
'users',
],
MIDDLEWARE=[],
)


@override_settings(**token_override_settings)
class TestSocialAuth1Token(APITestCase, BaseTwitterApiTestCase):

def test_login_social_oauth1_token(self):
"""
Currently oauth1 works only if session is enabled.
Probably it is possible to make it work without session, but
it will be needed to change the logic in python-social-auth.
"""
resp = self.client.post(
reverse('login_social_token_user'), data={'provider': 'twitter'})
url = reverse('login_social_token_user')
resp = self.client.post(url, data={'provider': 'twitter'})
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.data, parse_qs(self.request_token_body))
resp = self.client.post(reverse('login_social_token_user'), data={
Expand All @@ -46,9 +38,9 @@ def test_login_social_oauth1_token(self):
self.assertEqual(resp.status_code, 200)


@override_settings(**token_override_settings)
class TestSocialAuth2Token(APITestCase, BaseFacebookAPITestCase):

@modify_settings(**token_modify_settings)
def _check_login_social_token_user(self, url, data):
resp = self.client.post(url, data)
self.assertEqual(resp.status_code, 200)
Expand All @@ -58,7 +50,6 @@ def _check_login_social_token_user(self, url, data):
# check user is created
self.assertEqual(token.user.email, self.email)

@modify_settings(**token_modify_settings)
def _check_login_social_token_only(self, url, data):
resp = self.client.post(url, data)
self.assertEqual(resp.status_code, 200)
Expand Down

0 comments on commit 2973975

Please sign in to comment.