Commit 54f4d660 authored by Michael Fladischer's avatar Michael Fladischer

New upstream version 1.2.1

parent b7f1d97a
Metadata-Version: 1.1 Metadata-Version: 1.1
Name: djoser Name: djoser
Version: 1.1.5 Version: 1.2.1
Summary: REST version of Django authentication system. Summary: REST version of Django authentication system.
Home-page: https://github.com/sunscrapers/djoser Home-page: https://github.com/sunscrapers/djoser
Author: SUNSCRAPERS Author: SUNSCRAPERS
Author-email: info@sunscrapers.com Author-email: info@sunscrapers.com
License: MIT License: MIT
Description-Content-Type: UNKNOWN
Description: ====== Description: ======
djoser djoser
====== ======
...@@ -14,7 +13,7 @@ Description: ====== ...@@ -14,7 +13,7 @@ Description: ======
.. image:: https://img.shields.io/pypi/v/djoser.svg .. image:: https://img.shields.io/pypi/v/djoser.svg
:target: https://pypi.org/project/djoser :target: https://pypi.org/project/djoser
.. image:: https://img.shields.io/travis/sunscrapers/djoser.svg .. image:: https://img.shields.io/travis/sunscrapers/djoser/master.svg
:target: https://travis-ci.org/sunscrapers/djoser :target: https://travis-ci.org/sunscrapers/djoser
.. image:: https://img.shields.io/codecov/c/github/sunscrapers/djoser.svg .. image:: https://img.shields.io/codecov/c/github/sunscrapers/djoser.svg
...@@ -44,8 +43,9 @@ Description: ====== ...@@ -44,8 +43,9 @@ Description: ======
To be able to run **djoser** you have to meet following requirements: To be able to run **djoser** you have to meet following requirements:
- Python (2.7, 3.4, 3.5, 3.6) - Python (2.7, 3.4, 3.5, 3.6)
- Django (1.10, 1.11) - Django (1.11, 2.0)
- Django REST Framework (3.7) - Django REST Framework (3.7, 3.8)
Installation Installation
============ ============
...@@ -128,8 +128,9 @@ Description: ====== ...@@ -128,8 +128,9 @@ Description: ======
Platform: UNKNOWN Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: Django Classifier: Framework :: Django
Classifier: Framework :: Django :: 1.10
Classifier: Framework :: Django :: 1.11 Classifier: Framework :: Django :: 1.11
Classifier: Framework :: Django :: 2.0
Classifier: Framework :: Django :: 2.1
Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent Classifier: Operating System :: OS Independent
...@@ -138,3 +139,4 @@ Classifier: Programming Language :: Python :: 2.7 ...@@ -138,3 +139,4 @@ Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
...@@ -5,7 +5,7 @@ djoser ...@@ -5,7 +5,7 @@ djoser
.. image:: https://img.shields.io/pypi/v/djoser.svg .. image:: https://img.shields.io/pypi/v/djoser.svg
:target: https://pypi.org/project/djoser :target: https://pypi.org/project/djoser
.. image:: https://img.shields.io/travis/sunscrapers/djoser.svg .. image:: https://img.shields.io/travis/sunscrapers/djoser/master.svg
:target: https://travis-ci.org/sunscrapers/djoser :target: https://travis-ci.org/sunscrapers/djoser
.. image:: https://img.shields.io/codecov/c/github/sunscrapers/djoser.svg .. image:: https://img.shields.io/codecov/c/github/sunscrapers/djoser.svg
...@@ -35,8 +35,9 @@ Requirements ...@@ -35,8 +35,9 @@ Requirements
To be able to run **djoser** you have to meet following requirements: To be able to run **djoser** you have to meet following requirements:
- Python (2.7, 3.4, 3.5, 3.6) - Python (2.7, 3.4, 3.5, 3.6)
- Django (1.10, 1.11) - Django (1.11, 2.0)
- Django REST Framework (3.7) - Django REST Framework (3.7, 3.8)
Installation Installation
============ ============
......
Metadata-Version: 1.1 Metadata-Version: 1.1
Name: djoser Name: djoser
Version: 1.1.5 Version: 1.2.1
Summary: REST version of Django authentication system. Summary: REST version of Django authentication system.
Home-page: https://github.com/sunscrapers/djoser Home-page: https://github.com/sunscrapers/djoser
Author: SUNSCRAPERS Author: SUNSCRAPERS
Author-email: info@sunscrapers.com Author-email: info@sunscrapers.com
License: MIT License: MIT
Description-Content-Type: UNKNOWN
Description: ====== Description: ======
djoser djoser
====== ======
...@@ -14,7 +13,7 @@ Description: ====== ...@@ -14,7 +13,7 @@ Description: ======
.. image:: https://img.shields.io/pypi/v/djoser.svg .. image:: https://img.shields.io/pypi/v/djoser.svg
:target: https://pypi.org/project/djoser :target: https://pypi.org/project/djoser
.. image:: https://img.shields.io/travis/sunscrapers/djoser.svg .. image:: https://img.shields.io/travis/sunscrapers/djoser/master.svg
:target: https://travis-ci.org/sunscrapers/djoser :target: https://travis-ci.org/sunscrapers/djoser
.. image:: https://img.shields.io/codecov/c/github/sunscrapers/djoser.svg .. image:: https://img.shields.io/codecov/c/github/sunscrapers/djoser.svg
...@@ -44,8 +43,9 @@ Description: ====== ...@@ -44,8 +43,9 @@ Description: ======
To be able to run **djoser** you have to meet following requirements: To be able to run **djoser** you have to meet following requirements:
- Python (2.7, 3.4, 3.5, 3.6) - Python (2.7, 3.4, 3.5, 3.6)
- Django (1.10, 1.11) - Django (1.11, 2.0)
- Django REST Framework (3.7) - Django REST Framework (3.7, 3.8)
Installation Installation
============ ============
...@@ -128,8 +128,9 @@ Description: ====== ...@@ -128,8 +128,9 @@ Description: ======
Platform: UNKNOWN Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: Django Classifier: Framework :: Django
Classifier: Framework :: Django :: 1.10
Classifier: Framework :: Django :: 1.11 Classifier: Framework :: Django :: 1.11
Classifier: Framework :: Django :: 2.0
Classifier: Framework :: Django :: 2.1
Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent Classifier: Operating System :: OS Independent
...@@ -138,3 +139,4 @@ Classifier: Programming Language :: Python :: 2.7 ...@@ -138,3 +139,4 @@ Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
...@@ -9,7 +9,4 @@ def get_user_email(user): ...@@ -9,7 +9,4 @@ def get_user_email(user):
def get_user_email_field_name(user): def get_user_email_field_name(user):
try: # Assume we are Django >= 1.11 return user.get_email_field_name()
return user.get_email_field_name()
except AttributeError: # we are using Django < 1.11
return settings.USER_EMAIL_FIELD_NAME
...@@ -5,13 +5,23 @@ from djoser import views ...@@ -5,13 +5,23 @@ from djoser import views
urlpatterns = [ urlpatterns = [
url( url(
r'^token/create/$', r'^token/create/?$',
views.TokenCreateView.as_view(), views.TokenCreateView.as_view(),
name='token-create' name='token-create'
), ),
url( url(
r'^token/destroy/$', r'^token/destroy/?$',
views.TokenDestroyView.as_view(), views.TokenDestroyView.as_view(),
name='token-destroy' name='token-destroy'
), ),
url(
r'^token/login/?$',
views.TokenCreateView.as_view(),
name='login'
),
url(
r'^token/logout/?$',
views.TokenDestroyView.as_view(),
name='logout'
),
] ]
from django.conf.urls import url from django.conf.urls import url, include
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from djoser import views from djoser import views
User = get_user_model() from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('users', views.UserViewSet)
User = get_user_model()
urlpatterns = [ urlpatterns = [
url(r'^me/$', views.UserView.as_view(), name='user'), url(r'^me/?$', views.UserView.as_view(), name='user'),
url( url(
r'^users/create/$', r'^users/create/?$',
views.UserCreateView.as_view(), views.UserCreateView.as_view(),
name='user-create' name='user-create'
), ),
url( url(
r'^users/delete/$', r'^users/delete/?$',
views.UserDeleteView.as_view(), views.UserDeleteView.as_view(),
name='user-delete' name='user-delete'
), ),
url( url(
r'^users/activate/$', r'^users/activate/?$',
views.ActivationView.as_view(), views.ActivationView.as_view(),
name='user-activate' name='user-activate'
), ),
url( url(
r'^{0}/$'.format(User.USERNAME_FIELD), r'^{0}/?$'.format(User.USERNAME_FIELD),
views.SetUsernameView.as_view(), views.SetUsernameView.as_view(),
name='set_username' name='set_username'
), ),
url(r'^password/$', views.SetPasswordView.as_view(), name='set_password'), url(r'^password/?$', views.SetPasswordView.as_view(), name='set_password'),
url( url(
r'^password/reset/$', r'^password/reset/?$',
views.PasswordResetView.as_view(), views.PasswordResetView.as_view(),
name='password_reset' name='password_reset'
), ),
url( url(
r'^password/reset/confirm/$', r'^password/reset/confirm/?$',
views.PasswordResetConfirmView.as_view(), views.PasswordResetConfirmView.as_view(),
name='password_reset_confirm' name='password_reset_confirm'
), ),
url(r'^$', views.RootView.as_view(), name='root'), url(r'^$', views.RootView.as_view(), name='root'),
url(r'^', include(router.urls)),
] ]
...@@ -4,7 +4,7 @@ from rest_framework_jwt import views ...@@ -4,7 +4,7 @@ from rest_framework_jwt import views
urlpatterns = [ urlpatterns = [
url(r'^jwt/create/', views.obtain_jwt_token, name='jwt-create'), url(r'^jwt/create/?', views.obtain_jwt_token, name='jwt-create'),
url(r'^jwt/refresh/', views.refresh_jwt_token, name='jwt-refresh'), url(r'^jwt/refresh/?', views.refresh_jwt_token, name='jwt-refresh'),
url(r'^jwt/verify/', views.verify_jwt_token, name='jwt-verify'), url(r'^jwt/verify/?', views.verify_jwt_token, name='jwt-verify'),
] ]
...@@ -20,10 +20,11 @@ def login_user(request, user): ...@@ -20,10 +20,11 @@ def login_user(request, user):
def logout_user(request): def logout_user(request):
settings.TOKEN_MODEL.objects.filter(user=request.user).delete() if settings.TOKEN_MODEL:
user_logged_out.send( settings.TOKEN_MODEL.objects.filter(user=request.user).delete()
sender=request.user.__class__, request=request, user=request.user user_logged_out.send(
) sender=request.user.__class__, request=request, user=request.user
)
class ActionViewMixin(object): class ActionViewMixin(object):
......
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.tokens import default_token_generator from django.contrib.auth.tokens import default_token_generator
from django.urls.exceptions import NoReverseMatch from django.urls.exceptions import NoReverseMatch
from rest_framework import generics, permissions, status, views, viewsets
from rest_framework import generics, permissions, status, views from rest_framework.decorators import list_route
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.reverse import reverse from rest_framework.reverse import reverse
...@@ -19,10 +19,19 @@ class RootView(views.APIView): ...@@ -19,10 +19,19 @@ class RootView(views.APIView):
""" """
permission_classes = [permissions.AllowAny] permission_classes = [permissions.AllowAny]
def _get_url_names(self, urllist):
names = []
for entry in urllist:
if hasattr(entry, 'url_patterns'):
names.extend(self._get_url_names(entry.url_patterns))
else:
names.append(entry.name)
return names
def aggregate_djoser_urlpattern_names(self): def aggregate_djoser_urlpattern_names(self):
from djoser.urls import base, authtoken from djoser.urls import base, authtoken
urlpattern_names = [pattern.name for pattern in base.urlpatterns] urlpattern_names = self._get_url_names(base.urlpatterns)
urlpattern_names += [pattern.name for pattern in authtoken.urlpatterns] urlpattern_names += self._get_url_names(authtoken.urlpatterns)
urlpattern_names += self._get_jwt_urlpatterns() urlpattern_names += self._get_jwt_urlpatterns()
return urlpattern_names return urlpattern_names
...@@ -45,7 +54,7 @@ class RootView(views.APIView): ...@@ -45,7 +54,7 @@ class RootView(views.APIView):
def _get_jwt_urlpatterns(self): def _get_jwt_urlpatterns(self):
try: try:
from djoser.urls import jwt from djoser.urls import jwt
return [pattern.name for pattern in jwt.urlpatterns] return self._get_url_names(jwt.urlpatterns)
except ImportError: except ImportError:
return [] return []
...@@ -258,3 +267,100 @@ class UserView(generics.RetrieveUpdateAPIView): ...@@ -258,3 +267,100 @@ class UserView(generics.RetrieveUpdateAPIView):
context = {'user': user} context = {'user': user}
to = [get_user_email(user)] to = [get_user_email(user)]
settings.EMAIL.activation(self.request, context).send(to) settings.EMAIL.activation(self.request, context).send(to)
class UserViewSet(UserCreateView, viewsets.ModelViewSet):
serializer_class = settings.SERIALIZERS.user
queryset = User.objects.all()
permission_classes = [permissions.IsAuthenticated]
token_generator = default_token_generator
def get_permissions(self):
if self.action in ['create', 'confirm']:
self.permission_classes = [permissions.AllowAny]
elif self.action == 'list':
self.permission_classes = [permissions.IsAdminUser]
return super(UserViewSet, self).get_permissions()
def get_serializer_class(self):
if self.action == 'create':
return settings.SERIALIZERS.user_create
elif self.action == 'remove' or (
self.action == 'me' and self.request.method == 'DELETE'):
return settings.SERIALIZERS.user_delete
elif self.action == 'confirm':
return settings.SERIALIZERS.activation
elif self.action == 'change_username':
if settings.SET_USERNAME_RETYPE:
return settings.SERIALIZERS.set_username_retype
return settings.SERIALIZERS.set_username
return self.serializer_class
def get_instance(self):
return self.request.user
def perform_update(self, serializer):
super(UserViewSet, self).perform_update(serializer)
user = serializer.instance
if settings.SEND_ACTIVATION_EMAIL and not user.is_active:
context = {'user': user}
to = [get_user_email(user)]
settings.EMAIL.activation(self.request, context).send(to)
def perform_destroy(self, instance):
utils.logout_user(self.request)
super(UserViewSet, self).perform_destroy(instance)
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT)
@list_route(['get', 'put', 'patch', 'delete'])
def me(self, request, *args, **kwargs):
self.get_object = self.get_instance
if request.method == 'GET':
return self.retrieve(request, *args, **kwargs)
elif request.method in ['PUT', 'PATCH']:
return self.update(request, *args, **kwargs)
elif request.method == 'DELETE':
return self.destroy(request, *args, **kwargs)
@list_route(['post'])
def confirm(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.user
user.is_active = True
user.save()
signals.user_activated.send(
sender=self.__class__, user=user, request=self.request
)
if settings.SEND_CONFIRMATION_EMAIL:
context = {'user': user}
to = [get_user_email(user)]
settings.EMAIL.confirmation(self.request, context).send(to)
return Response(status=status.HTTP_204_NO_CONTENT)
@list_route(['post'])
def change_username(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = self.request.user
new_username = serializer.data['new_' + User.USERNAME_FIELD]
setattr(user, User.USERNAME_FIELD, new_username)
if settings.SEND_ACTIVATION_EMAIL:
user.is_active = False
context = {'user': user}
to = [get_user_email(user)]
settings.EMAIL.activation(self.request, context).send(to)
user.save()
return Response(status=status.HTTP_204_NO_CONTENT)
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
django-templated-mail==1.0.0 django-templated-mail==1.0.0
djangorestframework-jwt==1.11.0 djangorestframework-jwt==1.11.0
djet==0.2.1 djet==0.2.1
social-auth-app-django==2.0.0 social-auth-app-django==2.1.0
coverage==4.3.1 coverage==4.4.1
pytest==3.1.3 pytest==3.6.2
pytest-cov==2.5.1 pytest-cov==2.5.1
pytest-django==3.1.2 pytest-django==3.3.2
flake8==3.4.1 pytest-pythonpath==0.7.2
\ No newline at end of file flake8==3.5.0
#!/usr/bin/env python #!/usr/bin/env python
import os import os
from setuptools import setup
from setuptools import setup
with open('README.rst', 'r') as f: with open('README.rst', 'r') as f:
readme = f.read() readme = f.read()
...@@ -17,7 +17,7 @@ def get_packages(package): ...@@ -17,7 +17,7 @@ def get_packages(package):
setup( setup(
name='djoser', name='djoser',
version='1.1.5', version='1.2.1',
packages=get_packages('djoser'), packages=get_packages('djoser'),
license='MIT', license='MIT',
author='SUNSCRAPERS', author='SUNSCRAPERS',
...@@ -30,8 +30,9 @@ setup( ...@@ -30,8 +30,9 @@ setup(
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Framework :: Django', 'Framework :: Django',
'Framework :: Django :: 1.10',
'Framework :: Django :: 1.11', 'Framework :: Django :: 1.11',
'Framework :: Django :: 2.0',
'Framework :: Django :: 2.1',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License', 'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
...@@ -40,5 +41,6 @@ setup( ...@@ -40,5 +41,6 @@ setup(
'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
] ]
) )
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment