version 0.0.5.2: added method to revoke an access or refresh token

This commit is contained in:
Anatoly 2019-08-09 10:43:29 +03:00
parent 22f2de94f2
commit d0c362c88d
4 changed files with 69 additions and 30 deletions

View File

@ -3,8 +3,8 @@ from rest_framework import serializers
from authorization.models import Application
class SocialSignUpSerialzier(serializers.Serializer):
"""Serializer for signing up"""
class OAuth2Serialzier(serializers.Serializer):
"""Serializer OAuth2 authorization"""
source = serializers.ChoiceField(choices=Application.SOURCES)
token = serializers.CharField(max_length=255)

View File

@ -32,13 +32,12 @@ urlpatterns_rest_framework_social_oauth2 = [
url(r'^authorize/?$', AuthorizationView.as_view(), name="authorize"),
url(r'^token/?$', TokenView.as_view(), name="token"),
url('', include('social_django.urls', namespace="social")),
url(r'^convert-token/?$', ConvertTokenView.as_view(), name="convert_token"),
url(r'^revoke-token/?$', RevokeTokenView.as_view(), name="revoke_token"),
url(r'^invalidate-sessions/?$', invalidate_sessions, name="invalidate_sessions")
]
urlpatterns_api = [
path('social/signup/', views.SocialSignUpView.as_view(), name='signup'),
path('revoke-token/', views.RevokeTokenView.as_view(), name="revoke_token"),
]
urlpatterns = urlpatterns_api + \

View File

@ -2,35 +2,25 @@
import json
from braces.views import CsrfExemptMixin
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from oauth2_provider.oauth2_backends import OAuthLibCore
from oauth2_provider.settings import oauth2_settings
from oauth2_provider.views.mixins import OAuthLibMixin
from rest_framework import permissions
from authorization.models import Application
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from rest_framework.response import Response
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework_social_oauth2.oauth2_backends import KeepRequestCore
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
# Create your views here.
class SocialSignUpView(CsrfExemptMixin, OAuthLibMixin, GenericAPIView):
"""
Implements an endpoint to convert a provider token to an access token
The endpoint is used in the following flows:
* Authorization code
* Client credentials
"""
server_class = SocialTokenServer
validator_class = oauth2_settings.OAUTH2_VALIDATOR_CLASS
oauthlib_backend_class = KeepRequestCore
permission_classes = (permissions.AllowAny,)
serializer_class = serializers.SocialSignUpSerialzier
# Mixins
class OAuth2ViewMixin(GenericAPIView):
"""Basic mixin for OAuth2 views"""
def get_client_id(self, source) -> str:
"""Get application client id"""
@ -50,16 +40,15 @@ class SocialSignUpView(CsrfExemptMixin, OAuthLibMixin, GenericAPIView):
raise utils_exceptions.SerivceError(
data=_('Not found an application with this source'))
def post(self, request, *args, **kwargs):
"""Override POST method"""
# Serialize POST-data
serializer = self.get_serializer(data=request.data)
def prepare_request_data(self, request_data):
"""Preparing request data"""
serializer = self.get_serializer(data=request_data)
serializer.is_valid(raise_exception=True)
# Set attributes
source = serializer.validated_data.get('source')
token = serializer.validated_data.get('token')
# Set OAuth2 request parameters
request_data = {
_request_data = {
'grant_type': settings.OAUTH2_SOCIAL_AUTH_GRANT_TYPE,
'backend': settings.OAUTH2_SOCIAL_AUTH_BACKEND_NAME,
'token': token,
@ -67,8 +56,31 @@ class SocialSignUpView(CsrfExemptMixin, OAuthLibMixin, GenericAPIView):
}
# Fill client secret parameter by platform
if source == Application.MOBILE:
request_data['client_secret'] = self.get_client_secret(source)
_request_data['client_secret'] = self.get_client_secret(source)
return _request_data
# Create your views here.
class SocialSignUpView(CsrfExemptMixin, OAuthLibMixin,
OAuth2ViewMixin, GenericAPIView):
"""
Implements an endpoint to convert a provider token to an access token
The endpoint is used in the following flows:
* Authorization code
* Client credentials
"""
server_class = SocialTokenServer
validator_class = oauth2_settings.OAUTH2_VALIDATOR_CLASS
oauthlib_backend_class = KeepRequestCore
permission_classes = (permissions.AllowAny,)
serializer_class = serializers.OAuth2Serialzier
def post(self, request, *args, **kwargs):
"""Override POST method"""
# Preparing request data
request_data = self.prepare_request_data(request_data=request.data)
# 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():
@ -80,3 +92,31 @@ class SocialSignUpView(CsrfExemptMixin, OAuthLibMixin, GenericAPIView):
for k, v in headers.items():
response[k] = v
return response
class RevokeTokenView(CsrfExemptMixin, OAuthLibMixin,
OAuth2ViewMixin, GenericAPIView):
"""
Implements an endpoint to revoke access or refresh tokens
"""
server_class = oauth2_settings.OAUTH2_SERVER_CLASS
validator_class = oauth2_settings.OAUTH2_VALIDATOR_CLASS
oauthlib_backend_class = OAuthLibCore
permission_classes = (permissions.AllowAny,)
serializer_class = serializers.OAuth2Serialzier
def post(self, request, *args, **kwargs):
# Use the rest framework `.data` to fake the post body of the django request.
# Preparing request data
request_data = self.prepare_request_data(request_data=request.data)
# 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, status = self.create_revocation_response(request._request)
response = Response(data=json.loads(body) if body else '', status=status if body else 204)
for k, v in headers.items():
response[k] = v
return response

View File

@ -33,4 +33,4 @@ class GMOAuth2(DjangoOAuth2):
user = User.objects.get(pk=response[self.ID_KEY])
return user
else:
return None
return None