version 0.0.5.10: added endpoint to refresh token

This commit is contained in:
Anatoly 2019-08-12 12:55:08 +03:00
parent 60ea46592f
commit c9c5534cf0
4 changed files with 63 additions and 0 deletions

View File

@ -75,6 +75,11 @@ class LoginSerializer(BaseAuthSerializerMixin, serializers.ModelSerializer):
fields = ('username', 'password', 'source')
class RefreshTokenSerializer(BaseAuthSerializerMixin):
"""Serializer for refresh token view"""
refresh_token = serializers.CharField(write_only=True)
class LoginByEmailSerializer(LoginSerializerMixin, serializers.ModelSerializer):
"""Serializer for signing up user by email"""
email = serializers.EmailField(write_only=True)

View File

@ -46,6 +46,8 @@ urlpatterns_api = [
# logout
path('logout/', views.LogoutView.as_view(), name="logout"),
path('revoke-token/', views.RevokeTokenView.as_view(), name="revoke-token"),
# refresh token
path('refresh-token/', views.RefreshTokenView.as_view(), name="refresh-token"),
]
urlpatterns = urlpatterns_api + \

View File

@ -17,6 +17,7 @@ from rest_framework_social_oauth2.oauth2_endpoints import SocialTokenServer
from authorization.models import Application
from authorization.serializers import common as serializers
from utils import exceptions as utils_exceptions
from utils import permissions as utils_permissions
# Mixins
@ -227,6 +228,40 @@ class RevokeTokenView(OAuth2ViewMixin, GenericAPIView):
return response
class RefreshTokenView(OAuth2ViewMixin, GenericAPIView):
"""
Implements an endpoint to provide access tokens
The endpoint is used in the following flows:
* Authorization code
* Password
* Client credentials
"""
permission_classes = (utils_permissions.IsAuthenticatedAndHasRefreshToken, )
serializer_class = serializers.RefreshTokenSerializer
def post(self, request, *args, **kwargs):
# Preparing request data
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
request_data = self.prepare_request_data(serializer.validated_data)
request_data.update({
'grant_type': 'refresh_token',
'refresh_token': serializer.validated_data.get('refresh_token')
})
# Use the rest framework `.data` to fake the post body of the django request.
request._request.POST = request._request.POST.copy()
for key, value in request_data.items():
request._request.POST[key] = value
url, headers, body, oauth2_status = self.create_token_response(request._request)
response = Response(data=json.loads(body), status=oauth2_status)
for k, v in headers.items():
response[k] = v
return response
# Utils
class TokenView(CsrfExemptMixin, OAuthLibMixin, GenericAPIView):
"""

21
apps/utils/permissions.py Normal file
View File

@ -0,0 +1,21 @@
"""Project custom permissions"""
from rest_framework.permissions import BasePermission
class IsAuthenticatedAndHasRefreshToken(BasePermission):
"""
Check if requested user is authenticated and has refresh token
"""
def has_permission(self, request, view):
token = request.data.get('refresh_token')
user = request.user
if token and hasattr(user, 'oauth2_provider_refreshtoken'):
refresh_token_qs = user.oauth2_provider_refreshtoken
return (
user.is_authenticated and
user.is_active and
refresh_token_qs.filter(token=token).exists()
)
else:
return False