diff -Nru djoser-0.5.2/debian/changelog djoser-0.6.0/debian/changelog --- djoser-0.5.2/debian/changelog 2017-01-09 10:51:12.000000000 +0000 +++ djoser-0.6.0/debian/changelog 2017-06-20 18:44:32.000000000 +0000 @@ -1,3 +1,10 @@ +djoser (0.6.0-1) unstable; urgency=low + + * New upstream release. + * Bump Standards-Version to 4.0.0. + + -- Michael Fladischer Tue, 20 Jun 2017 20:44:32 +0200 + djoser (0.5.2-1) unstable; urgency=low * New upstream release. diff -Nru djoser-0.5.2/debian/control djoser-0.6.0/debian/control --- djoser-0.5.2/debian/control 2017-01-09 10:51:12.000000000 +0000 +++ djoser-0.6.0/debian/control 2017-06-20 18:44:32.000000000 +0000 @@ -15,7 +15,7 @@ python3-djangorestframework (>= 3), python3-pypandoc, python3-setuptools -Standards-Version: 3.9.8 +Standards-Version: 4.0.0 X-Python-Version: >= 2.7 X-Python3-Version: >= 3.4 Homepage: https://github.com/sunscrapers/djoser diff -Nru djoser-0.5.2/debian/.git-dpm djoser-0.6.0/debian/.git-dpm --- djoser-0.5.2/debian/.git-dpm 2017-01-09 10:51:12.000000000 +0000 +++ djoser-0.6.0/debian/.git-dpm 2017-06-20 18:44:32.000000000 +0000 @@ -1,8 +1,8 @@ # see git-dpm(1) from git-dpm package -9230373435bca320b048f3260fb06fa49846bdfa -9230373435bca320b048f3260fb06fa49846bdfa -9230373435bca320b048f3260fb06fa49846bdfa -9230373435bca320b048f3260fb06fa49846bdfa -djoser_0.5.2.orig.tar.gz -ff330d398cb2e47520f5c0c38225b45fa06d3eca -14789 +a294649eef57aaf30ef05da4080ae93b5b23461f +a294649eef57aaf30ef05da4080ae93b5b23461f +a294649eef57aaf30ef05da4080ae93b5b23461f +a294649eef57aaf30ef05da4080ae93b5b23461f +djoser_0.6.0.orig.tar.gz +36406feb28d612b2d7b9b1938253c4b5ec94ce55 +8992 diff -Nru djoser-0.5.2/djoser/constants.py djoser-0.6.0/djoser/constants.py --- djoser-0.5.2/djoser/constants.py 2016-12-30 10:08:54.000000000 +0000 +++ djoser-0.6.0/djoser/constants.py 2017-06-02 08:32:41.000000000 +0000 @@ -9,3 +9,4 @@ USERNAME_MISMATCH_ERROR = _('The two {0} fields didn\'t match.') INVALID_PASSWORD_ERROR = _('Invalid password.') EMAIL_NOT_FOUND = _('User with given email does not exist.') +CANNOT_CREATE_USER_ERROR = _('Unable to create account.') diff -Nru djoser-0.5.2/djoser/serializers.py djoser-0.6.0/djoser/serializers.py --- djoser-0.5.2/djoser/serializers.py 2016-12-30 10:08:54.000000000 +0000 +++ djoser-0.6.0/djoser/serializers.py 2017-06-02 08:32:41.000000000 +0000 @@ -1,5 +1,5 @@ from django.contrib.auth import authenticate, get_user_model -from django.db import transaction +from django.db import IntegrityError, transaction from django.utils import six from django.utils.module_loading import import_string @@ -8,12 +8,10 @@ from . import constants, utils, settings - User = get_user_model() class UserSerializer(serializers.ModelSerializer): - class Meta: model = User fields = tuple(User.REQUIRED_FIELDS) + ( @@ -26,31 +24,45 @@ class UserRegistrationSerializer(serializers.ModelSerializer): - password = serializers.CharField(style={'input_type': 'password'}, - write_only=True, - validators=settings.get('PASSWORD_VALIDATORS')) + password = serializers.CharField( + style={'input_type': 'password'}, + write_only=True, + validators=settings.get('PASSWORD_VALIDATORS') + ) + + default_error_messages = { + 'cannot_create_user': constants.CANNOT_CREATE_USER_ERROR, + } class Meta: model = User fields = tuple(User.REQUIRED_FIELDS) + ( - User.USERNAME_FIELD, - User._meta.pk.name, - 'password', + User.USERNAME_FIELD, User._meta.pk.name, 'password', ) def create(self, validated_data): - if settings.get('SEND_ACTIVATION_EMAIL'): - with transaction.atomic(): - user = User.objects.create_user(**validated_data) + try: + user = self.perform_create(validated_data) + except IntegrityError: + raise serializers.ValidationError( + self.error_messages['cannot_create_user'] + ) + + return user + + def perform_create(self, validated_data): + with transaction.atomic(): + user = User.objects.create_user(**validated_data) + if settings.get('SEND_ACTIVATION_EMAIL'): user.is_active = False user.save(update_fields=['is_active']) - else: - user = User.objects.create_user(**validated_data) return user class LoginSerializer(serializers.Serializer): - password = serializers.CharField(required=False, style={'input_type': 'password'}) + password = serializers.CharField( + required=False, style={'input_type': 'password'} + ) default_error_messages = { 'inactive_account': constants.INACTIVE_ACCOUNT_ERROR, @@ -63,13 +75,20 @@ self.fields[User.USERNAME_FIELD] = serializers.CharField(required=False) def validate(self, attrs): - self.user = authenticate(username=attrs.get(User.USERNAME_FIELD), password=attrs.get('password')) + self.user = authenticate( + username=attrs.get(User.USERNAME_FIELD), + password=attrs.get('password') + ) if self.user: if not self.user.is_active: - raise serializers.ValidationError(self.error_messages['inactive_account']) + raise serializers.ValidationError( + self.error_messages['inactive_account'] + ) return attrs else: - raise serializers.ValidationError(self.error_messages['invalid_credentials']) + raise serializers.ValidationError( + self.error_messages['invalid_credentials'] + ) class PasswordResetSerializer(serializers.Serializer): diff -Nru djoser-0.5.2/djoser/utils.py djoser-0.6.0/djoser/utils.py --- djoser-0.5.2/djoser/utils.py 2016-12-30 10:08:54.000000000 +0000 +++ djoser-0.6.0/djoser/utils.py 2017-05-26 08:56:36.000000000 +0000 @@ -28,11 +28,12 @@ def logout_user(request): authtoken.models.Token.objects.filter(user=request.user).delete() - user_logged_out.send(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): - def post(self, request): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) @@ -45,44 +46,60 @@ plain_body_template_name = None html_body_template_name = None - def __init__(self, from_email, user, protocol, domain, site_name): + def __init__(self, from_email, user, protocol, domain, site_name, **context): self.from_email = from_email self.user = user self.domain = domain self.site_name = site_name self.protocol = protocol + self.context_data = context @classmethod - def from_request(cls, request, user=None, from_email=None): + def from_request(cls, request, user=None, from_email=None, **context): site = get_current_site(request) + from_email = from_email or getattr( + django_settings, 'DEFAULT_FROM_EMAIL', '' + ) + return cls( - from_email=getattr(django_settings, 'DEFAULT_FROM_EMAIL', from_email), + from_email=from_email, user=user or request.user, domain=django_settings.DJOSER.get('DOMAIN') or site.domain, site_name=django_settings.DJOSER.get('SITE_NAME') or site.name, protocol='https' if request.is_secure() else 'http', + **context ) - def create(self,): + def create(self): assert self.plain_body_template_name or self.html_body_template_name context = self.get_context() subject = loader.render_to_string(self.subject_template_name, context) subject = ''.join(subject.splitlines()) if self.plain_body_template_name: - plain_body = loader.render_to_string(self.plain_body_template_name, context) - email_message = EmailMultiAlternatives(subject, plain_body, self.from_email, [self.user.email]) + plain_body = loader.render_to_string( + self.plain_body_template_name, context + ) + email_message = EmailMultiAlternatives( + subject, plain_body, self.from_email, [self.user.email] + ) if self.html_body_template_name: - html_body = loader.render_to_string(self.html_body_template_name, context) + html_body = loader.render_to_string( + self.html_body_template_name, context + ) email_message.attach_alternative(html_body, 'text/html') else: - html_body = loader.render_to_string(self.html_body_template_name, context) - email_message = EmailMessage(subject, html_body, self.from_email, [self.user.email]) + html_body = loader.render_to_string( + self.html_body_template_name, context + ) + email_message = EmailMessage( + subject, html_body, self.from_email, [self.user.email] + ) email_message.content_subtype = 'html' return email_message def get_context(self): - return { + context = { 'user': self.user, 'domain': self.domain, 'site_name': self.site_name, @@ -90,6 +107,8 @@ 'token': self.token_generator.make_token(self.user), 'protocol': self.protocol, } + context.update(self.context_data) + return context class UserActivationEmailFactory(UserEmailFactoryBase): @@ -108,7 +127,9 @@ def get_context(self): context = super(UserPasswordResetEmailFactory, self).get_context() - context['url'] = settings.get('PASSWORD_RESET_CONFIRM_URL').format(**context) + context['url'] = settings.get('PASSWORD_RESET_CONFIRM_URL').format( + **context + ) return context diff -Nru djoser-0.5.2/djoser/views.py djoser-0.6.0/djoser/views.py --- djoser-0.5.2/djoser/views.py 2016-12-30 10:08:54.000000000 +0000 +++ djoser-0.6.0/djoser/views.py 2017-06-02 08:32:41.000000000 +0000 @@ -1,13 +1,12 @@ from django.contrib.auth.tokens import default_token_generator from django.contrib.auth import get_user_model -from rest_framework import generics, permissions, status, response, views +from rest_framework import generics, permissions, status, views from rest_framework.response import Response from rest_framework.reverse import reverse from . import serializers, settings, utils, signals - User = get_user_model() @@ -55,27 +54,28 @@ def perform_create(self, serializer): user = serializer.save() - signals.user_registered.send(sender=self.__class__, user=user, request=self.request) + signals.user_registered.send( + sender=self.__class__, user=user, request=self.request + ) if settings.get('SEND_ACTIVATION_EMAIL'): self.send_activation_email(user) elif settings.get('SEND_CONFIRMATION_EMAIL'): self.send_confirmation_email(user) def send_activation_email(self, user): - email_factory = utils.UserActivationEmailFactory.from_request(self.request, user=user) + email_factory = utils.UserActivationEmailFactory.from_request( + self.request, user=user + ) email = email_factory.create() email.send() def send_confirmation_email(self, user): - email_factory = utils.UserConfirmationEmailFactory.from_request(self.request, user=user) + email_factory = utils.UserConfirmationEmailFactory.from_request( + self.request, user=user + ) email = email_factory.create() email.send() - def get_email_context(self, user): - context = super(RegistrationView, self).get_email_context(user) - context['url'] = settings.get('ACTIVATION_URL').format(**context) - return context - class LoginView(utils.ActionViewMixin, generics.GenericAPIView): """ @@ -105,7 +105,7 @@ def post(self, request): utils.logout_user(request) - return response.Response(status=status.HTTP_204_NO_CONTENT) + return Response(status=status.HTTP_204_NO_CONTENT) class PasswordResetView(utils.ActionViewMixin, generics.GenericAPIView): @@ -122,7 +122,7 @@ def _action(self, serializer): for user in self.get_users(serializer.data['email']): self.send_password_reset_email(user) - return response.Response(status=status.HTTP_204_NO_CONTENT) + return Response(status=status.HTTP_204_NO_CONTENT) def get_users(self, email): if self._users is None: @@ -159,7 +159,7 @@ if settings.get('LOGOUT_ON_PASSWORD_CHANGE'): utils.logout_user(self.request) - return response.Response(status=status.HTTP_204_NO_CONTENT) + return Response(status=status.HTTP_204_NO_CONTENT) class PasswordResetConfirmView(utils.ActionViewMixin, generics.GenericAPIView): @@ -179,7 +179,7 @@ def _action(self, serializer): serializer.user.set_password(serializer.data['new_password']) serializer.user.save() - return response.Response(status=status.HTTP_204_NO_CONTENT) + return Response(status=status.HTTP_204_NO_CONTENT) class ActivationView(utils.ActionViewMixin, generics.GenericAPIView): @@ -221,7 +221,7 @@ def _action(self, serializer): setattr(self.request.user, User.USERNAME_FIELD, serializer.data['new_' + User.USERNAME_FIELD]) self.request.user.save() - return response.Response(status=status.HTTP_204_NO_CONTENT) + return Response(status=status.HTTP_204_NO_CONTENT) class UserView(generics.RetrieveUpdateAPIView): diff -Nru djoser-0.5.2/djoser.egg-info/PKG-INFO djoser-0.6.0/djoser.egg-info/PKG-INFO --- djoser-0.5.2/djoser.egg-info/PKG-INFO 2017-01-02 12:01:28.000000000 +0000 +++ djoser-0.6.0/djoser.egg-info/PKG-INFO 2017-06-02 13:32:50.000000000 +0000 @@ -1,801 +1,82 @@ Metadata-Version: 1.1 Name: djoser -Version: 0.5.2 +Version: 0.6.0 Summary: REST version of Django authentication system. Home-page: https://github.com/sunscrapers/djoser Author: SUNSCRAPERS Author-email: info@sunscrapers.com License: MIT -Description: djoser - ====== +Description: # djoser - |Build Status| |Coverage Status| + [![Build Status](https://travis-ci.org/sunscrapers/djoser.svg?branch=master)](https://travis-ci.org/sunscrapers/djoser) + [![Coverage Status](https://coveralls.io/repos/sunscrapers/djoser/badge.png?branch=master)](https://coveralls.io/r/sunscrapers/djoser?branch=master) - REST implementation of `Django `__ - authentication system. **Djoser** library provides a set of `Django Rest - Framework `__ views to handle - basic actions such as registration, login, logout, password reset and - account activation. It works with `custom user - model `__. - - Instead of reusing Django code (e.g. ``PasswordResetForm``), we - reimplemented few things to fit better into `Single Page - App `__ - architecture. - - Developed by `SUNSCRAPERS `__ with passion & - patience. - - Features - -------- - - Here is a list of supported authentication backends: - - - `HTTP Basic - Auth `__ - (Default) - - `Token based authentication from Django Rest - Framework `__ - - Available endpoints: - - - ``/me/`` - - ``/register/`` - - ``/login/`` (token based authentication) - - ``/logout/`` (token based authentication) - - ``/activate/`` - - ``/{{ User.USERNAME_FIELD }}/`` - - ``/password/`` - - ``/password/reset/`` - - ``/password/reset/confirm/`` - - Supported Python versions: - - - Python 2.7 - - Python 3.4 - - Python 3.5 - - Supported Django versions: - - - Django 1.7 - - Django 1.8 - - Django 1.9 - - Django 1.10 - - Supported Django Rest Framework versions: - - - Django Rest Framework 3.x - - For Django Rest Framework 2.4 support check `djoser - 0.3.2 `__. - - Installation - ------------ - - Use ``pip``: - - :: - - $ pip install djoser - - Quick Start - ----------- - - Configure ``INSTALLED_APPS``: - - .. code:: python - - INSTALLED_APPS = ( - 'django.contrib.auth', - (...), - 'rest_framework', - 'djoser', - (...), - ) - - Configure ``urls.py``: - - .. code:: python - - urlpatterns = patterns('', - (...), - url(r'^auth/', include('djoser.urls')), - ) - - HTTP Basic Auth strategy is assumed by default as Django Rest Framework - does it. However you may want to set it explicitly: - - .. code:: python - - REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'rest_framework.authentication.BasicAuthentication', - ), - } - - Run migrations - this step will create tables for ``auth`` app: - - :: - - $ ./manage.py migrate - - Customizing authentication backend - ---------------------------------- - - Token Based Authentication - ~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Add ``'rest_framework.authtoken'`` to ``INSTALLED_APPS``: - - .. code:: python - - INSTALLED_APPS = ( - 'django.contrib.auth', - (...), - 'rest_framework', - 'rest_framework.authtoken', - 'djoser', - (...), - ) - - Configure ``urls.py``. Pay attention to ``djoser.url.authtoken`` module - path. - - .. code:: python - - urlpatterns = patterns('', - (...), - url(r'^auth/', include('djoser.urls.authtoken')), - ) - - Set ``TokenAuthentication`` as default Django Rest Framework - authentication strategy: - - .. code:: python - - REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'rest_framework.authentication.TokenAuthentication', - ), - } - - Run migrations - this step will create tables for ``auth`` and - ``authtoken`` apps: - - :: - - $ ./manage.py migrate - - JSON Web Token Authentication - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - ``djoser`` does not provide support for JSON web token authentication - out of the box but can be enabled by using a library like - `djangorestframework-jwt `__. - - You simply need to route correctly in your ``settings.ROOT_URLCONF``. An - example would be: - - :: - - import rest_framework_jwt.views - import djoser.views - - urlpatterns = [ - url(r'^auth/login', rest_framework_jwt.views.obtain_jwt_token), # using JSON web token - url(r'^auth/register', djoser.views.RegistrationView.as_view()), - url(r'^auth/password/reset', djoser.views.PasswordResetView.as_view()), - url(r'^auth/password/reset/confirm', djoser.views.PasswordResetConfirmView.as_view()), - ... - ] - - Settings - -------- - - Optionally add ``DJOSER`` settings: - - .. code:: python - - DJOSER = { - 'DOMAIN': 'frontend.com', - 'SITE_NAME': 'Frontend', - 'PASSWORD_RESET_CONFIRM_URL': '#/password/reset/confirm/{uid}/{token}', - 'ACTIVATION_URL': '#/activate/{uid}/{token}', - 'SEND_ACTIVATION_EMAIL': True, - 'PASSWORD_VALIDATORS': [], - 'SERIALIZERS': {}, - } - - Check "Settings" section for more info. - - Endpoints - --------- - - User - ~~~~ - - Use this endpoint to retrieve/update user. - - ``GET`` - ^^^^^^^ - - URL: ``/me/`` - - Retrieve user. - - - **response** - - - status: ``HTTP_200_OK`` (success) - - - data: - - ``{{ User.USERNAME_FIELD }}`` - - ``{{ User._meta.pk.name }}`` - - ``{{ User.REQUIRED_FIELDS }}`` - - ``PUT`` - ^^^^^^^ - - URL: ``/me/`` - - Update user. - - - **request** - - - data: - - ``{{ User.REQUIRED_FIELDS }}`` - - - **response** - - - status: ``HTTP_200_OK`` (success) - - - data: - - ``{{ User.USERNAME_FIELD }}`` - - ``{{ User._meta.pk.name }}`` - - ``{{ User.REQUIRED_FIELDS }}`` - - Register - ~~~~~~~~ - - Use this endpoint to register new user. Your user model manager should - implement - `create\_user `__ - method and have - `USERNAME\_FIELD `__ - and - `REQUIRED\_FIELDS `__ - fields. - - ``POST`` - ^^^^^^^^ - - URL: ``/register/`` - - - **request** - - - data: - - ``{{ User.USERNAME_FIELD }}`` - - ``{{ User.REQUIRED_FIELDS }}`` - - ``password`` - - - **response** - - - status: ``HTTP_201_CREATED`` (success) - - - data: - - ``{{ User.USERNAME_FIELD }}`` - - ``{{ User._meta.pk.name }}`` - - ``{{ User.REQUIRED_FIELDS }}`` - - Login - ~~~~~ - - Use this endpoint to obtain user `authentication - token `__. - This endpoint is available only if you are using token based - authentication. - - ``POST`` - ^^^^^^^^ - - URL: ``/login/`` - - - **request** - - - data: - - ``{{ User.USERNAME_FIELD }}`` - - ``password`` - - - **response** - - - status: ``HTTP_200_OK`` (success) - - - data: - - ``auth_token`` - - Logout - ~~~~~~ - - Use this endpoint to logout user (remove user authentication token). - This endpoint is available only if you are using token based - authentication. - - ``POST`` - ^^^^^^^^ - - URL: ``/logout/`` - - - **response** - - - status: ``HTTP_204_NO_CONTENT`` (success) - - Activate - ~~~~~~~~ - - Use this endpoint to activate user account. This endpoint is not a URL - which will be directly exposed to your users - you should provide site - in your frontend application (configured by ``ACTIVATION_URL``) which - will send ``POST`` request to activate endpoint. - - ``POST`` - ^^^^^^^^ - - URL: ``/activate/`` - - - **request** - - - data: - - ``uid`` - - ``token`` - - - **response** - - - status: ``HTTP_204_NO_CONTENT`` (success) - - Set username - ~~~~~~~~~~~~ - - Use this endpoint to change user username (``USERNAME_FIELD``). - - ``POST`` - ^^^^^^^^ - - URL: ``/{{ User.USERNAME_FIELD }}/`` - - - **request** - - - data: - - ``new_{{ User.USERNAME_FIELD }}`` - - ``re_new_{{ User.USERNAME_FIELD }}`` (if ``SET_USERNAME_RETYPE`` - is ``True``) + REST implementation of [Django](https://www.djangoproject.com/) authentication + system. **Djoser** library provides a set of [Django Rest Framework](http://www.django-rest-framework.org/) + views to handle basic actions such as registration, login, logout, password + reset and account activation. It works with [custom user model](https://docs.djangoproject.com/en/dev/topics/auth/customizing/). - ``current_password`` - - - **response** - - - status: ``HTTP_204_NO_CONTENT`` (success) - - Set password - ~~~~~~~~~~~~ - - Use this endpoint to change user password. - - ``POST`` - ^^^^^^^^ - - URL: ``/password/`` - - - **request** - - - data: - - ``new_password`` - - ``re_new_password`` (if ``SET_PASSWORD_RETYPE`` is ``True``) - - ``current_password`` - - - **response** - - - status: ``HTTP_204_NO_CONTENT`` (success) - - Reset password - ~~~~~~~~~~~~~~ - - Use this endpoint to send email to user with password reset link. You - have to setup ``PASSWORD_RESET_CONFIRM_URL``. - - ``POST`` - ^^^^^^^^ - - URL: ``/password/reset/`` - - - **request** - - - data: - - ``email`` - - - **response** - - - status: ``HTTP_204_NO_CONTENT`` (success), if - ``PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND`` is ``False`` (default); or - - status: ``HTTP_400_BAD_REQUEST``, if - ``PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND`` is ``True`` and ``email`` - does not exists in the database. - - Reset password confirmation - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Use this endpoint to finish reset password process. This endpoint is not - a URL which will be directly exposed to your users - you should provide - site in your frontend application (configured by - ``PASSWORD_RESET_CONFIRM_URL``) which will send ``POST`` request to - reset password confirmation endpoint. - - ``POST`` - ^^^^^^^^ - - URL: ``/password/reset/confirm/`` - - - **request** - - - data: - - ``uid`` - - ``token`` - - ``new_password`` - - ``re_new_password`` (if ``PASSWORD_RESET_CONFIRM_RETYPE`` is - ``True``) - - - **response** - - - status: ``HTTP_204_NO_CONTENT`` (success) - - Settings - -------- - - DOMAIN - ~~~~~~ - - Domain of your frontend app. If not provided, domain of current site - will be used. - - **Required**: ``False`` - - SITE\_NAME - ~~~~~~~~~~ - - Name of your frontend app. If not provided, name of current site will be - used. - - **Required**: ``False`` - - PASSWORD\_RESET\_CONFIRM\_URL - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - URL to your frontend password reset page. It should contain ``{uid}`` - and ``{token}`` placeholders, e.g. ``#/password-reset/{uid}/{token}``. - You should pass ``uid`` and ``token`` to reset password confirmation - endpoint. - - **Required**: ``True`` - - SEND\_ACTIVATION\_EMAIL - ~~~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, register endpoint will send activation email to user. - - **Default**: ``False`` - - SEND\_CONFIRMATION\_EMAIL - ~~~~~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, register or activation endpoint will send confirmation - email to user. - - **Default**: ``False`` - - ACTIVATION\_URL - ~~~~~~~~~~~~~~~ - - URL to your frontend activation page. It should contain ``{uid}`` and - ``{token}`` placeholders, e.g. ``#/activate/{uid}/{token}``. You should - pass ``uid`` and ``token`` to activation endpoint. - - **Required**: ``True`` - - SET\_USERNAME\_RETYPE - ~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, you need to pass ``re_new_{{ User.USERNAME_FIELD }}`` to - ``/{{ User.USERNAME_FIELD }}/`` endpoint, to validate username equality. - - **Default**: ``False`` - - SET\_PASSWORD\_RETYPE - ~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, you need to pass ``re_new_password`` to ``/password/`` - endpoint, to validate password equality. - - **Default**: ``False`` - - PASSWORD\_RESET\_CONFIRM\_RETYPE - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, you need to pass ``re_new_password`` to - ``/password/reset/confirm/`` endpoint in order to validate password - equality. - - **Default**: ``False`` - - LOGOUT\_ON\_PASSWORD\_CHANGE - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, setting new password will logout the user. - - **Default**: ``False`` - - PASSWORD\_RESET\_SHOW\_EMAIL\_NOT\_FOUND - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, posting a non-existent ``email`` to ``/password/reset/`` - will return a ``HTTP_400_BAD_REQUEST`` response with an - ``EMAIL_NOT_FOUND`` error message ('User with given email does not - exist.'). - - If ``False`` (default), the ``/password/reset/`` endpoint will always - return a ``HTTP_204_NO_CONTENT`` response. - - Please note that setting this to ``True`` will expose information - whether an email is registered in the system. - - **Default**: ``False`` - - PASSWORD\_VALIDATORS - ~~~~~~~~~~~~~~~~~~~~ - - List containing `REST Framework - Validator `__ - functions. These validators are run on ``/register/`` and - ``/password/reset/confirm/``. - - **Default**: ``[]`` - - **Example**: ``[my_validator1, my_validator2]`` - - SERIALIZERS - ~~~~~~~~~~~ - - This dictionary is used to update the defaults, so by providing, let's - say, one key, all the others will still be used. - - **Examples** - - :: - - { - 'user': 'myapp.serializers.SpecialUserSerializer', - } - - **Default**: - - :: - - { - 'activation': 'djoser.serializers.ActivationSerializer', - 'login': 'djoser.serializers.LoginSerializer', - 'password_reset': 'djoser.serializers.PasswordResetSerializer', - 'password_reset_confirm': 'djoser.serializers.PasswordResetConfirmSerializer', - 'password_reset_confirm_retype': 'djoser.serializers.PasswordResetConfirmRetypeSerializer', - 'set_password': 'djoser.serializers.SetPasswordSerializer', - 'set_password_retype': 'djoser.serializers.SetPasswordRetypeSerializer', - 'set_username': 'djoser.serializers.SetUsernameSerializer', - 'set_username_retype': 'djoser.serializers.SetUsernameRetypeSerializer', - 'user_registration': 'djoser.serializers.UserRegistrationSerializer', - 'user': 'djoser.serializers.UserSerializer', - 'token': 'djoser.serializers.TokenSerializer', - } - - Emails - ------ - - There are few email templates which you may want to override: - - - ``activation_email_body.txt`` - - ``activation_email_subject.txt`` - - ``password_reset_email_body.txt`` - - ``password_reset_email_subject.txt`` - - All of them have following context: - - - ``user`` - - ``domain`` - - ``site_name`` - - ``url`` - - ``uid`` - - ``token`` - - ``protocol`` - - Sample usage - ------------ - - We provide a standalone test app for you to start easily, see how - everything works with basic settings. It might be useful before - integrating **djoser** into your backend application. - - In this extremely short tutorial we are going to mimic the simplest - flow: register user, log in and log out. We will also check resource - access on each consecutive step. Let's go! - - - Clone repository and install **djoser** to your virtualenv: - - ``$ git clone git@github.com:sunscrapers/djoser.git`` - - ``$ cd djoser`` - - ``$ pip install -e .`` - - - Go to the ``testproject`` directory, migrate the database and start - the development server: - - ``$ cd testproject`` - - ``$ ./manage.py migrate`` - - ``$ ./manage.py runserver 8088`` - - - Register a new user: - - ``$ curl -X POST http://127.0.0.1:8088/auth/register/ --data 'username=djoser&password=djoser'`` - - ``{"email": "", "username": "djoser", "id":1}`` - - So far, so good. We have just created a new user using REST API. - - - Let's access user's details: - - ``$ curl -X GET http://127.0.0.1:8088/auth/me/`` - - ``{"detail": "Authentication credentials were not provided."}`` - - As we can see, we cannot access user profile without logging in. - Pretty obvious. - - - Let's log in: - - ``curl -X POST http://127.0.0.1:8088/auth/login/ --data 'username=djoser&password=djoser'`` - - ``{"auth_token": "b704c9fc3655635646356ac2950269f352ea1139"}`` - - We have just obtained an authorization token that we may use later in - order to retrieve specific resources. - - - Let's access user's details again: - - ``$ curl -X GET http://127.0.0.1:8088/auth/me/`` - - ``{"detail": "Authentication credentials were not provided."}`` - - Access is still forbidden but let's offer the token we obtained: - - ``$ curl -X GET http://127.0.0.1:8088/auth/me/ -H 'Authorization: Token b704c9fc3655635646356ac2950269f352ea1139'`` - - ``{"email": "", "username": "djoser", "id": 1}`` - - Yay, it works! - - - Now let's log out: - - ``curl -X POST http://127.0.0.1:8088/auth/logout/ -H 'Authorization: Token b704c9fc3655635646356ac2950269f352ea1139'`` - - And try access user profile again: - - ``$ curl -X GET http://127.0.0.1:8088/auth/me/ -H 'Authorization: Token b704c9fc3655635646356ac2950269f352ea1139'`` - - ``{"detail": "Invalid token"}`` - - As we can see, user has been logged out successfully and the proper - token has been removed. - - Customization - ------------- - - If you need to customize any serializer behaviour you can use the - DJOSER['SERIALIZERS'] setting to use your own serializer classes in the - built-in views. Or if you need to completely change the default djoser - behaviour, you can always override djoser views with your own custom - ones. - - Define custom ``urls`` instead of reusing ``djoser.urls``: - - .. code:: python + Instead of reusing Django code (e.g. `PasswordResetForm`), we reimplemented + few things to fit better into [Single Page App](http://en.wikipedia.org/wiki/Single-page_application) + architecture. - urlpatterns = patterns('', - (...), - url(r'^register/$', views.CustomRegistrationView.as_view()), - ) + Developed by [SUNSCRAPERS](http://sunscrapers.com/) with passion & patience. - Define custom view/serializer (inherit from one of ``djoser`` class) and - override necessary method/field: - .. code:: python + ## Documentation - class CustomRegistrationView(djoser.views.RegistrationView): + Documentation is available to study at + [http://djoser.readthedocs.io](http://djoser.readthedocs.io) and in + `docs` directory. - def send_activation_email(self, *args, **kwargs): - your_custom_email_sender(*args, **kwargs) + ## Contributing and development - You could check ``djoser`` API in source code: + To start developing on **djoser**, clone the repository: - - `djoser.views `__ - - `djoser.serializers `__ + `$ git clone git@github.com:sunscrapers/djoser.git` - Development - ----------- + If you are a **pipenv** user you can quickly setup testing environment by + using Make commands: - To start developing on **djoser**, clone the repository: + `$ make init` + `$ make test` - ``$ git clone git@github.com:sunscrapers/djoser.git`` + You do not need to create virtualenv in this case - + it's automatically created for you. - In order to run the tests create virtualenv, go to repo directory and - then: + Otherwise, if you cannot use Make commands, please create virtualenv and install + requirements manually: - ``$ pip install -r requirements-test.txt`` + `$ pip install django djangorestframework` + `$ pip install -r requirements.txt` - ``$ cd testproject`` + If you are running djoser tests on Python 2.7 you also need to install `mock` library. - ``$ ./manage.py migrate`` + `$ pip install mock # only on Python 2.7` + `$ cd testproject` + `$ ./manage.py test` - ``$ ./manage.py test`` + If you need to run tests against all supported Python and Django versions then invoke: - If you need to run tests against all supported Python and Django - versions then invoke: + `$ pip install tox` + `$ tox` - ``$ pip install tox`` + You can also play with test project by running following commands: - ``$ tox`` + `$ ./manage.py migrate` + `$ ./manage.py runserver` - Similar projects - ---------------- + ## Similar projects List of projects related to Django, REST and authentication: - - `django-rest-auth `__ - - `django-rest-framework-digestauth `__ - - `django-oauth-toolkit `__ - - `doac `__ - - `django-rest-framework-jwt `__ - - `django-rest-framework-httpsignature `__ - - `hawkrest `__ - - .. |Build Status| image:: https://travis-ci.org/sunscrapers/djoser.svg?branch=master - :target: https://travis-ci.org/sunscrapers/djoser - .. |Coverage Status| image:: https://coveralls.io/repos/sunscrapers/djoser/badge.png?branch=master - :target: https://coveralls.io/r/sunscrapers/djoser?branch=master + - [django-rest-auth](https://github.com/Tivix/django-rest-auth) + - [django-rest-framework-digestauth](https://github.com/juanriaza/django-rest-framework-digestauth) + - [django-oauth-toolkit](https://github.com/evonove/django-oauth-toolkit) + - [doac](https://github.com/Rediker-Software/doac) + - [django-rest-framework-jwt](https://github.com/GetBlimp/django-rest-framework-jwt) + - [django-rest-framework-httpsignature](https://github.com/etoccalino/django-rest-framework-httpsignature) + - [hawkrest](https://github.com/kumar303/hawkrest) Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha diff -Nru djoser-0.5.2/djoser.egg-info/requires.txt djoser-0.6.0/djoser.egg-info/requires.txt --- djoser-0.5.2/djoser.egg-info/requires.txt 2017-01-02 12:01:28.000000000 +0000 +++ djoser-0.6.0/djoser.egg-info/requires.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -Django>=1.7 -djangorestframework>=3.0.0 diff -Nru djoser-0.5.2/djoser.egg-info/SOURCES.txt djoser-0.6.0/djoser.egg-info/SOURCES.txt --- djoser-0.5.2/djoser.egg-info/SOURCES.txt 2017-01-02 12:01:28.000000000 +0000 +++ djoser-0.6.0/djoser.egg-info/SOURCES.txt 2017-06-02 13:32:50.000000000 +0000 @@ -12,7 +12,6 @@ djoser.egg-info/PKG-INFO djoser.egg-info/SOURCES.txt djoser.egg-info/dependency_links.txt -djoser.egg-info/requires.txt djoser.egg-info/top_level.txt djoser/templates/activation_email_body.txt djoser/templates/activation_email_subject.txt diff -Nru djoser-0.5.2/PKG-INFO djoser-0.6.0/PKG-INFO --- djoser-0.5.2/PKG-INFO 2017-01-02 12:01:28.000000000 +0000 +++ djoser-0.6.0/PKG-INFO 2017-06-02 13:32:50.000000000 +0000 @@ -1,801 +1,82 @@ Metadata-Version: 1.1 Name: djoser -Version: 0.5.2 +Version: 0.6.0 Summary: REST version of Django authentication system. Home-page: https://github.com/sunscrapers/djoser Author: SUNSCRAPERS Author-email: info@sunscrapers.com License: MIT -Description: djoser - ====== +Description: # djoser - |Build Status| |Coverage Status| + [![Build Status](https://travis-ci.org/sunscrapers/djoser.svg?branch=master)](https://travis-ci.org/sunscrapers/djoser) + [![Coverage Status](https://coveralls.io/repos/sunscrapers/djoser/badge.png?branch=master)](https://coveralls.io/r/sunscrapers/djoser?branch=master) - REST implementation of `Django `__ - authentication system. **Djoser** library provides a set of `Django Rest - Framework `__ views to handle - basic actions such as registration, login, logout, password reset and - account activation. It works with `custom user - model `__. - - Instead of reusing Django code (e.g. ``PasswordResetForm``), we - reimplemented few things to fit better into `Single Page - App `__ - architecture. - - Developed by `SUNSCRAPERS `__ with passion & - patience. - - Features - -------- - - Here is a list of supported authentication backends: - - - `HTTP Basic - Auth `__ - (Default) - - `Token based authentication from Django Rest - Framework `__ - - Available endpoints: - - - ``/me/`` - - ``/register/`` - - ``/login/`` (token based authentication) - - ``/logout/`` (token based authentication) - - ``/activate/`` - - ``/{{ User.USERNAME_FIELD }}/`` - - ``/password/`` - - ``/password/reset/`` - - ``/password/reset/confirm/`` - - Supported Python versions: - - - Python 2.7 - - Python 3.4 - - Python 3.5 - - Supported Django versions: - - - Django 1.7 - - Django 1.8 - - Django 1.9 - - Django 1.10 - - Supported Django Rest Framework versions: - - - Django Rest Framework 3.x - - For Django Rest Framework 2.4 support check `djoser - 0.3.2 `__. - - Installation - ------------ - - Use ``pip``: - - :: - - $ pip install djoser - - Quick Start - ----------- - - Configure ``INSTALLED_APPS``: - - .. code:: python - - INSTALLED_APPS = ( - 'django.contrib.auth', - (...), - 'rest_framework', - 'djoser', - (...), - ) - - Configure ``urls.py``: - - .. code:: python - - urlpatterns = patterns('', - (...), - url(r'^auth/', include('djoser.urls')), - ) - - HTTP Basic Auth strategy is assumed by default as Django Rest Framework - does it. However you may want to set it explicitly: - - .. code:: python - - REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'rest_framework.authentication.BasicAuthentication', - ), - } - - Run migrations - this step will create tables for ``auth`` app: - - :: - - $ ./manage.py migrate - - Customizing authentication backend - ---------------------------------- - - Token Based Authentication - ~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Add ``'rest_framework.authtoken'`` to ``INSTALLED_APPS``: - - .. code:: python - - INSTALLED_APPS = ( - 'django.contrib.auth', - (...), - 'rest_framework', - 'rest_framework.authtoken', - 'djoser', - (...), - ) - - Configure ``urls.py``. Pay attention to ``djoser.url.authtoken`` module - path. - - .. code:: python - - urlpatterns = patterns('', - (...), - url(r'^auth/', include('djoser.urls.authtoken')), - ) - - Set ``TokenAuthentication`` as default Django Rest Framework - authentication strategy: - - .. code:: python - - REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'rest_framework.authentication.TokenAuthentication', - ), - } - - Run migrations - this step will create tables for ``auth`` and - ``authtoken`` apps: - - :: - - $ ./manage.py migrate - - JSON Web Token Authentication - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - ``djoser`` does not provide support for JSON web token authentication - out of the box but can be enabled by using a library like - `djangorestframework-jwt `__. - - You simply need to route correctly in your ``settings.ROOT_URLCONF``. An - example would be: - - :: - - import rest_framework_jwt.views - import djoser.views - - urlpatterns = [ - url(r'^auth/login', rest_framework_jwt.views.obtain_jwt_token), # using JSON web token - url(r'^auth/register', djoser.views.RegistrationView.as_view()), - url(r'^auth/password/reset', djoser.views.PasswordResetView.as_view()), - url(r'^auth/password/reset/confirm', djoser.views.PasswordResetConfirmView.as_view()), - ... - ] - - Settings - -------- - - Optionally add ``DJOSER`` settings: - - .. code:: python - - DJOSER = { - 'DOMAIN': 'frontend.com', - 'SITE_NAME': 'Frontend', - 'PASSWORD_RESET_CONFIRM_URL': '#/password/reset/confirm/{uid}/{token}', - 'ACTIVATION_URL': '#/activate/{uid}/{token}', - 'SEND_ACTIVATION_EMAIL': True, - 'PASSWORD_VALIDATORS': [], - 'SERIALIZERS': {}, - } - - Check "Settings" section for more info. - - Endpoints - --------- - - User - ~~~~ - - Use this endpoint to retrieve/update user. - - ``GET`` - ^^^^^^^ - - URL: ``/me/`` - - Retrieve user. - - - **response** - - - status: ``HTTP_200_OK`` (success) - - - data: - - ``{{ User.USERNAME_FIELD }}`` - - ``{{ User._meta.pk.name }}`` - - ``{{ User.REQUIRED_FIELDS }}`` - - ``PUT`` - ^^^^^^^ - - URL: ``/me/`` - - Update user. - - - **request** - - - data: - - ``{{ User.REQUIRED_FIELDS }}`` - - - **response** - - - status: ``HTTP_200_OK`` (success) - - - data: - - ``{{ User.USERNAME_FIELD }}`` - - ``{{ User._meta.pk.name }}`` - - ``{{ User.REQUIRED_FIELDS }}`` - - Register - ~~~~~~~~ - - Use this endpoint to register new user. Your user model manager should - implement - `create\_user `__ - method and have - `USERNAME\_FIELD `__ - and - `REQUIRED\_FIELDS `__ - fields. - - ``POST`` - ^^^^^^^^ - - URL: ``/register/`` - - - **request** - - - data: - - ``{{ User.USERNAME_FIELD }}`` - - ``{{ User.REQUIRED_FIELDS }}`` - - ``password`` - - - **response** - - - status: ``HTTP_201_CREATED`` (success) - - - data: - - ``{{ User.USERNAME_FIELD }}`` - - ``{{ User._meta.pk.name }}`` - - ``{{ User.REQUIRED_FIELDS }}`` - - Login - ~~~~~ - - Use this endpoint to obtain user `authentication - token `__. - This endpoint is available only if you are using token based - authentication. - - ``POST`` - ^^^^^^^^ - - URL: ``/login/`` - - - **request** - - - data: - - ``{{ User.USERNAME_FIELD }}`` - - ``password`` - - - **response** - - - status: ``HTTP_200_OK`` (success) - - - data: - - ``auth_token`` - - Logout - ~~~~~~ - - Use this endpoint to logout user (remove user authentication token). - This endpoint is available only if you are using token based - authentication. - - ``POST`` - ^^^^^^^^ - - URL: ``/logout/`` - - - **response** - - - status: ``HTTP_204_NO_CONTENT`` (success) - - Activate - ~~~~~~~~ - - Use this endpoint to activate user account. This endpoint is not a URL - which will be directly exposed to your users - you should provide site - in your frontend application (configured by ``ACTIVATION_URL``) which - will send ``POST`` request to activate endpoint. - - ``POST`` - ^^^^^^^^ - - URL: ``/activate/`` - - - **request** - - - data: - - ``uid`` - - ``token`` - - - **response** - - - status: ``HTTP_204_NO_CONTENT`` (success) - - Set username - ~~~~~~~~~~~~ - - Use this endpoint to change user username (``USERNAME_FIELD``). - - ``POST`` - ^^^^^^^^ - - URL: ``/{{ User.USERNAME_FIELD }}/`` - - - **request** - - - data: - - ``new_{{ User.USERNAME_FIELD }}`` - - ``re_new_{{ User.USERNAME_FIELD }}`` (if ``SET_USERNAME_RETYPE`` - is ``True``) + REST implementation of [Django](https://www.djangoproject.com/) authentication + system. **Djoser** library provides a set of [Django Rest Framework](http://www.django-rest-framework.org/) + views to handle basic actions such as registration, login, logout, password + reset and account activation. It works with [custom user model](https://docs.djangoproject.com/en/dev/topics/auth/customizing/). - ``current_password`` - - - **response** - - - status: ``HTTP_204_NO_CONTENT`` (success) - - Set password - ~~~~~~~~~~~~ - - Use this endpoint to change user password. - - ``POST`` - ^^^^^^^^ - - URL: ``/password/`` - - - **request** - - - data: - - ``new_password`` - - ``re_new_password`` (if ``SET_PASSWORD_RETYPE`` is ``True``) - - ``current_password`` - - - **response** - - - status: ``HTTP_204_NO_CONTENT`` (success) - - Reset password - ~~~~~~~~~~~~~~ - - Use this endpoint to send email to user with password reset link. You - have to setup ``PASSWORD_RESET_CONFIRM_URL``. - - ``POST`` - ^^^^^^^^ - - URL: ``/password/reset/`` - - - **request** - - - data: - - ``email`` - - - **response** - - - status: ``HTTP_204_NO_CONTENT`` (success), if - ``PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND`` is ``False`` (default); or - - status: ``HTTP_400_BAD_REQUEST``, if - ``PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND`` is ``True`` and ``email`` - does not exists in the database. - - Reset password confirmation - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Use this endpoint to finish reset password process. This endpoint is not - a URL which will be directly exposed to your users - you should provide - site in your frontend application (configured by - ``PASSWORD_RESET_CONFIRM_URL``) which will send ``POST`` request to - reset password confirmation endpoint. - - ``POST`` - ^^^^^^^^ - - URL: ``/password/reset/confirm/`` - - - **request** - - - data: - - ``uid`` - - ``token`` - - ``new_password`` - - ``re_new_password`` (if ``PASSWORD_RESET_CONFIRM_RETYPE`` is - ``True``) - - - **response** - - - status: ``HTTP_204_NO_CONTENT`` (success) - - Settings - -------- - - DOMAIN - ~~~~~~ - - Domain of your frontend app. If not provided, domain of current site - will be used. - - **Required**: ``False`` - - SITE\_NAME - ~~~~~~~~~~ - - Name of your frontend app. If not provided, name of current site will be - used. - - **Required**: ``False`` - - PASSWORD\_RESET\_CONFIRM\_URL - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - URL to your frontend password reset page. It should contain ``{uid}`` - and ``{token}`` placeholders, e.g. ``#/password-reset/{uid}/{token}``. - You should pass ``uid`` and ``token`` to reset password confirmation - endpoint. - - **Required**: ``True`` - - SEND\_ACTIVATION\_EMAIL - ~~~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, register endpoint will send activation email to user. - - **Default**: ``False`` - - SEND\_CONFIRMATION\_EMAIL - ~~~~~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, register or activation endpoint will send confirmation - email to user. - - **Default**: ``False`` - - ACTIVATION\_URL - ~~~~~~~~~~~~~~~ - - URL to your frontend activation page. It should contain ``{uid}`` and - ``{token}`` placeholders, e.g. ``#/activate/{uid}/{token}``. You should - pass ``uid`` and ``token`` to activation endpoint. - - **Required**: ``True`` - - SET\_USERNAME\_RETYPE - ~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, you need to pass ``re_new_{{ User.USERNAME_FIELD }}`` to - ``/{{ User.USERNAME_FIELD }}/`` endpoint, to validate username equality. - - **Default**: ``False`` - - SET\_PASSWORD\_RETYPE - ~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, you need to pass ``re_new_password`` to ``/password/`` - endpoint, to validate password equality. - - **Default**: ``False`` - - PASSWORD\_RESET\_CONFIRM\_RETYPE - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, you need to pass ``re_new_password`` to - ``/password/reset/confirm/`` endpoint in order to validate password - equality. - - **Default**: ``False`` - - LOGOUT\_ON\_PASSWORD\_CHANGE - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, setting new password will logout the user. - - **Default**: ``False`` - - PASSWORD\_RESET\_SHOW\_EMAIL\_NOT\_FOUND - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - If ``True``, posting a non-existent ``email`` to ``/password/reset/`` - will return a ``HTTP_400_BAD_REQUEST`` response with an - ``EMAIL_NOT_FOUND`` error message ('User with given email does not - exist.'). - - If ``False`` (default), the ``/password/reset/`` endpoint will always - return a ``HTTP_204_NO_CONTENT`` response. - - Please note that setting this to ``True`` will expose information - whether an email is registered in the system. - - **Default**: ``False`` - - PASSWORD\_VALIDATORS - ~~~~~~~~~~~~~~~~~~~~ - - List containing `REST Framework - Validator `__ - functions. These validators are run on ``/register/`` and - ``/password/reset/confirm/``. - - **Default**: ``[]`` - - **Example**: ``[my_validator1, my_validator2]`` - - SERIALIZERS - ~~~~~~~~~~~ - - This dictionary is used to update the defaults, so by providing, let's - say, one key, all the others will still be used. - - **Examples** - - :: - - { - 'user': 'myapp.serializers.SpecialUserSerializer', - } - - **Default**: - - :: - - { - 'activation': 'djoser.serializers.ActivationSerializer', - 'login': 'djoser.serializers.LoginSerializer', - 'password_reset': 'djoser.serializers.PasswordResetSerializer', - 'password_reset_confirm': 'djoser.serializers.PasswordResetConfirmSerializer', - 'password_reset_confirm_retype': 'djoser.serializers.PasswordResetConfirmRetypeSerializer', - 'set_password': 'djoser.serializers.SetPasswordSerializer', - 'set_password_retype': 'djoser.serializers.SetPasswordRetypeSerializer', - 'set_username': 'djoser.serializers.SetUsernameSerializer', - 'set_username_retype': 'djoser.serializers.SetUsernameRetypeSerializer', - 'user_registration': 'djoser.serializers.UserRegistrationSerializer', - 'user': 'djoser.serializers.UserSerializer', - 'token': 'djoser.serializers.TokenSerializer', - } - - Emails - ------ - - There are few email templates which you may want to override: - - - ``activation_email_body.txt`` - - ``activation_email_subject.txt`` - - ``password_reset_email_body.txt`` - - ``password_reset_email_subject.txt`` - - All of them have following context: - - - ``user`` - - ``domain`` - - ``site_name`` - - ``url`` - - ``uid`` - - ``token`` - - ``protocol`` - - Sample usage - ------------ - - We provide a standalone test app for you to start easily, see how - everything works with basic settings. It might be useful before - integrating **djoser** into your backend application. - - In this extremely short tutorial we are going to mimic the simplest - flow: register user, log in and log out. We will also check resource - access on each consecutive step. Let's go! - - - Clone repository and install **djoser** to your virtualenv: - - ``$ git clone git@github.com:sunscrapers/djoser.git`` - - ``$ cd djoser`` - - ``$ pip install -e .`` - - - Go to the ``testproject`` directory, migrate the database and start - the development server: - - ``$ cd testproject`` - - ``$ ./manage.py migrate`` - - ``$ ./manage.py runserver 8088`` - - - Register a new user: - - ``$ curl -X POST http://127.0.0.1:8088/auth/register/ --data 'username=djoser&password=djoser'`` - - ``{"email": "", "username": "djoser", "id":1}`` - - So far, so good. We have just created a new user using REST API. - - - Let's access user's details: - - ``$ curl -X GET http://127.0.0.1:8088/auth/me/`` - - ``{"detail": "Authentication credentials were not provided."}`` - - As we can see, we cannot access user profile without logging in. - Pretty obvious. - - - Let's log in: - - ``curl -X POST http://127.0.0.1:8088/auth/login/ --data 'username=djoser&password=djoser'`` - - ``{"auth_token": "b704c9fc3655635646356ac2950269f352ea1139"}`` - - We have just obtained an authorization token that we may use later in - order to retrieve specific resources. - - - Let's access user's details again: - - ``$ curl -X GET http://127.0.0.1:8088/auth/me/`` - - ``{"detail": "Authentication credentials were not provided."}`` - - Access is still forbidden but let's offer the token we obtained: - - ``$ curl -X GET http://127.0.0.1:8088/auth/me/ -H 'Authorization: Token b704c9fc3655635646356ac2950269f352ea1139'`` - - ``{"email": "", "username": "djoser", "id": 1}`` - - Yay, it works! - - - Now let's log out: - - ``curl -X POST http://127.0.0.1:8088/auth/logout/ -H 'Authorization: Token b704c9fc3655635646356ac2950269f352ea1139'`` - - And try access user profile again: - - ``$ curl -X GET http://127.0.0.1:8088/auth/me/ -H 'Authorization: Token b704c9fc3655635646356ac2950269f352ea1139'`` - - ``{"detail": "Invalid token"}`` - - As we can see, user has been logged out successfully and the proper - token has been removed. - - Customization - ------------- - - If you need to customize any serializer behaviour you can use the - DJOSER['SERIALIZERS'] setting to use your own serializer classes in the - built-in views. Or if you need to completely change the default djoser - behaviour, you can always override djoser views with your own custom - ones. - - Define custom ``urls`` instead of reusing ``djoser.urls``: - - .. code:: python + Instead of reusing Django code (e.g. `PasswordResetForm`), we reimplemented + few things to fit better into [Single Page App](http://en.wikipedia.org/wiki/Single-page_application) + architecture. - urlpatterns = patterns('', - (...), - url(r'^register/$', views.CustomRegistrationView.as_view()), - ) + Developed by [SUNSCRAPERS](http://sunscrapers.com/) with passion & patience. - Define custom view/serializer (inherit from one of ``djoser`` class) and - override necessary method/field: - .. code:: python + ## Documentation - class CustomRegistrationView(djoser.views.RegistrationView): + Documentation is available to study at + [http://djoser.readthedocs.io](http://djoser.readthedocs.io) and in + `docs` directory. - def send_activation_email(self, *args, **kwargs): - your_custom_email_sender(*args, **kwargs) + ## Contributing and development - You could check ``djoser`` API in source code: + To start developing on **djoser**, clone the repository: - - `djoser.views `__ - - `djoser.serializers `__ + `$ git clone git@github.com:sunscrapers/djoser.git` - Development - ----------- + If you are a **pipenv** user you can quickly setup testing environment by + using Make commands: - To start developing on **djoser**, clone the repository: + `$ make init` + `$ make test` - ``$ git clone git@github.com:sunscrapers/djoser.git`` + You do not need to create virtualenv in this case - + it's automatically created for you. - In order to run the tests create virtualenv, go to repo directory and - then: + Otherwise, if you cannot use Make commands, please create virtualenv and install + requirements manually: - ``$ pip install -r requirements-test.txt`` + `$ pip install django djangorestframework` + `$ pip install -r requirements.txt` - ``$ cd testproject`` + If you are running djoser tests on Python 2.7 you also need to install `mock` library. - ``$ ./manage.py migrate`` + `$ pip install mock # only on Python 2.7` + `$ cd testproject` + `$ ./manage.py test` - ``$ ./manage.py test`` + If you need to run tests against all supported Python and Django versions then invoke: - If you need to run tests against all supported Python and Django - versions then invoke: + `$ pip install tox` + `$ tox` - ``$ pip install tox`` + You can also play with test project by running following commands: - ``$ tox`` + `$ ./manage.py migrate` + `$ ./manage.py runserver` - Similar projects - ---------------- + ## Similar projects List of projects related to Django, REST and authentication: - - `django-rest-auth `__ - - `django-rest-framework-digestauth `__ - - `django-oauth-toolkit `__ - - `doac `__ - - `django-rest-framework-jwt `__ - - `django-rest-framework-httpsignature `__ - - `hawkrest `__ - - .. |Build Status| image:: https://travis-ci.org/sunscrapers/djoser.svg?branch=master - :target: https://travis-ci.org/sunscrapers/djoser - .. |Coverage Status| image:: https://coveralls.io/repos/sunscrapers/djoser/badge.png?branch=master - :target: https://coveralls.io/r/sunscrapers/djoser?branch=master + - [django-rest-auth](https://github.com/Tivix/django-rest-auth) + - [django-rest-framework-digestauth](https://github.com/juanriaza/django-rest-framework-digestauth) + - [django-oauth-toolkit](https://github.com/evonove/django-oauth-toolkit) + - [doac](https://github.com/Rediker-Software/doac) + - [django-rest-framework-jwt](https://github.com/GetBlimp/django-rest-framework-jwt) + - [django-rest-framework-httpsignature](https://github.com/etoccalino/django-rest-framework-httpsignature) + - [hawkrest](https://github.com/kumar303/hawkrest) Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha diff -Nru djoser-0.5.2/README.md djoser-0.6.0/README.md --- djoser-0.5.2/README.md 2017-01-02 11:31:06.000000000 +0000 +++ djoser-0.6.0/README.md 2017-06-02 12:52:19.000000000 +0000 @@ -14,667 +14,50 @@ Developed by [SUNSCRAPERS](http://sunscrapers.com/) with passion & patience. -## Features -Here is a list of supported authentication backends: +## Documentation - * [HTTP Basic Auth](http://www.django-rest-framework.org/api-guide/authentication/#basicauthentication) (Default) - * [Token based authentication from Django Rest Framework](http://www.django-rest-framework.org/api-guide/authentication#tokenauthentication) +Documentation is available to study at +[http://djoser.readthedocs.io](http://djoser.readthedocs.io) and in +`docs` directory. -Available endpoints: - - * `/me/` - * `/register/` - * `/login/` (token based authentication) - * `/logout/` (token based authentication) - * `/activate/` - * `/{{ User.USERNAME_FIELD }}/` - * `/password/` - * `/password/reset/` - * `/password/reset/confirm/` - -Supported Python versions: - - * Python 2.7 - * Python 3.4 - * Python 3.5 - -Supported Django versions: - - * Django 1.7 - * Django 1.8 - * Django 1.9 - * Django 1.10 - -Supported Django Rest Framework versions: - - * Django Rest Framework 3.x - -For Django Rest Framework 2.4 support check [djoser 0.3.2](https://github.com/sunscrapers/djoser/tree/0.3.2). - -## Installation - -Use `pip`: - - $ pip install djoser - -## Quick Start - -Configure `INSTALLED_APPS`: - -```python -INSTALLED_APPS = ( - 'django.contrib.auth', - (...), - 'rest_framework', - 'djoser', - (...), -) -``` - -Configure `urls.py`: - -```python -urlpatterns = patterns('', - (...), - url(r'^auth/', include('djoser.urls')), -) -``` - -HTTP Basic Auth strategy is assumed by default as Django Rest Framework does it. However you may want to set it -explicitly: - -```python -REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'rest_framework.authentication.BasicAuthentication', - ), -} -``` - -Run migrations - this step will create tables for `auth` app: - - $ ./manage.py migrate - -## Customizing authentication backend - -### Token Based Authentication - -Add `'rest_framework.authtoken'` to `INSTALLED_APPS`: - -```python -INSTALLED_APPS = ( - 'django.contrib.auth', - (...), - 'rest_framework', - 'rest_framework.authtoken', - 'djoser', - (...), -) -``` - -Configure `urls.py`. Pay attention to `djoser.url.authtoken` module path. - -```python -urlpatterns = patterns('', - (...), - url(r'^auth/', include('djoser.urls.authtoken')), -) -``` - -Set `TokenAuthentication` as default Django Rest Framework authentication strategy: - -```python -REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'rest_framework.authentication.TokenAuthentication', - ), -} -``` - -Run migrations - this step will create tables for `auth` and `authtoken` apps: - - $ ./manage.py migrate - -### JSON Web Token Authentication -`djoser` does not provide support for JSON web token authentication out of the box but -can be enabled by using a library like [djangorestframework-jwt](https://github.com/GetBlimp/django-rest-framework-jwt). - -You simply need to route correctly in your `settings.ROOT_URLCONF`. An example would be: - -``` -import rest_framework_jwt.views -import djoser.views - -urlpatterns = [ - url(r'^auth/login', rest_framework_jwt.views.obtain_jwt_token), # using JSON web token - url(r'^auth/register', djoser.views.RegistrationView.as_view()), - url(r'^auth/password/reset', djoser.views.PasswordResetView.as_view()), - url(r'^auth/password/reset/confirm', djoser.views.PasswordResetConfirmView.as_view()), - ... -] -``` - -## Settings - -Optionally add `DJOSER` settings: - -```python -DJOSER = { - 'DOMAIN': 'frontend.com', - 'SITE_NAME': 'Frontend', - 'PASSWORD_RESET_CONFIRM_URL': '#/password/reset/confirm/{uid}/{token}', - 'ACTIVATION_URL': '#/activate/{uid}/{token}', - 'SEND_ACTIVATION_EMAIL': True, - 'PASSWORD_VALIDATORS': [], - 'SERIALIZERS': {}, -} -``` - -Check "Settings" section for more info. - -## Endpoints - -### User - -Use this endpoint to retrieve/update user. - -#### `GET` - -URL: `/me/` - -Retrieve user. - -* **response** - - * status: `HTTP_200_OK` (success) - - * data: - - `{{ User.USERNAME_FIELD }}` - - `{{ User._meta.pk.name }}` - - `{{ User.REQUIRED_FIELDS }}` - -#### `PUT` - -URL: `/me/` - -Update user. - -* **request** - - * data: - - `{{ User.REQUIRED_FIELDS }}` - -* **response** - - * status: `HTTP_200_OK` (success) - - * data: - - `{{ User.USERNAME_FIELD }}` - - `{{ User._meta.pk.name }}` - - `{{ User.REQUIRED_FIELDS }}` - -### Register - -Use this endpoint to register new user. Your user model manager should -implement [create_user](https://docs.djangoproject.com/en/dev/ref/contrib/auth/#django.contrib.auth.models.UserManager.create_user) -method and have [USERNAME_FIELD](https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.models.CustomUser.USERNAME_FIELD) -and [REQUIRED_FIELDS](https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.models.CustomUser.REQUIRED_FIELDS) -fields. - -#### `POST` - -URL: `/register/` - -* **request** - - * data: - - `{{ User.USERNAME_FIELD }}` - - `{{ User.REQUIRED_FIELDS }}` - - `password` - -* **response** - - * status: `HTTP_201_CREATED` (success) - - * data: - - `{{ User.USERNAME_FIELD }}` - - `{{ User._meta.pk.name }}` - - `{{ User.REQUIRED_FIELDS }}` - -### Login - -Use this endpoint to obtain user [authentication token](http://www.django-rest-framework.org/api-guide/authentication#tokenauthentication). -This endpoint is available only if you are using token based authentication. - -#### `POST` - -URL: `/login/` - -* **request** - - * data: - - `{{ User.USERNAME_FIELD }}` - - `password` - -* **response** - - * status: `HTTP_200_OK` (success) - - * data: - - `auth_token` - -### Logout - -Use this endpoint to logout user (remove user authentication token). This endpoint is available only if you are using -token based authentication. - -#### `POST` - -URL: `/logout/` - -* **response** - - * status: `HTTP_204_NO_CONTENT` (success) - -### Activate - -Use this endpoint to activate user account. This endpoint is not a URL which -will be directly exposed to your users - you should provide site in your -frontend application (configured by `ACTIVATION_URL`) which will send `POST` -request to activate endpoint. - -#### `POST` - -URL: `/activate/` - -* **request** - - * data: - - `uid` - - `token` - -* **response** - - * status: `HTTP_204_NO_CONTENT` (success) - -### Set username - -Use this endpoint to change user username (`USERNAME_FIELD`). - -#### `POST` - -URL: `/{{ User.USERNAME_FIELD }}/` - -* **request** - - * data: - - `new_{{ User.USERNAME_FIELD }}` - - `re_new_{{ User.USERNAME_FIELD }}` (if `SET_USERNAME_RETYPE` is `True`) - - `current_password` - -* **response** - - * status: `HTTP_204_NO_CONTENT` (success) - -### Set password - -Use this endpoint to change user password. - -#### `POST` - -URL: `/password/` - -* **request** - - * data: - - `new_password` - - `re_new_password` (if `SET_PASSWORD_RETYPE` is `True`) - - `current_password` - -* **response** - - * status: `HTTP_204_NO_CONTENT` (success) - -### Reset password - -Use this endpoint to send email to user with password reset link. You have to -setup `PASSWORD_RESET_CONFIRM_URL`. - -#### `POST` - -URL: `/password/reset/` - -* **request** - - * data: - - `email` - -* **response** - - * status: `HTTP_204_NO_CONTENT` (success), if `PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND` is `False` (default); or - * status: `HTTP_400_BAD_REQUEST`, if `PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND` is `True` and `email` does not exists in the database. - -### Reset password confirmation - -Use this endpoint to finish reset password process. This endpoint is not a URL -which will be directly exposed to your users - you should provide site in your -frontend application (configured by `PASSWORD_RESET_CONFIRM_URL`) which -will send `POST` request to reset password confirmation endpoint. - -#### `POST` - -URL: `/password/reset/confirm/` - -* **request** - - * data: - - `uid` - - `token` - - `new_password` - - `re_new_password` (if `PASSWORD_RESET_CONFIRM_RETYPE` is `True`) - -* **response** - - * status: `HTTP_204_NO_CONTENT` (success) - -## Settings - -### DOMAIN - -Domain of your frontend app. If not provided, domain of current site will be -used. - -**Required**: `False` - -### SITE_NAME - -Name of your frontend app. If not provided, name of current site will be -used. - -**Required**: `False` - -### PASSWORD_RESET_CONFIRM_URL - -URL to your frontend password reset page. It should contain `{uid}` and -`{token}` placeholders, e.g. `#/password-reset/{uid}/{token}`. You should pass -`uid` and `token` to reset password confirmation endpoint. - -**Required**: `True` - -### SEND_ACTIVATION_EMAIL - -If `True`, register endpoint will send activation email to user. - -**Default**: `False` - -### SEND_CONFIRMATION_EMAIL - -If `True`, register or activation endpoint will send confirmation email to user. - -**Default**: `False` - -### ACTIVATION_URL - -URL to your frontend activation page. It should contain `{uid}` and `{token}` -placeholders, e.g. `#/activate/{uid}/{token}`. You should pass `uid` and -`token` to activation endpoint. - -**Required**: `True` - -### SET_USERNAME_RETYPE - -If `True`, you need to pass `re_new_{{ User.USERNAME_FIELD }}` to -`/{{ User.USERNAME_FIELD }}/` endpoint, to validate username equality. - -**Default**: `False` - -### SET_PASSWORD_RETYPE - -If `True`, you need to pass `re_new_password` to `/password/` endpoint, to -validate password equality. - -**Default**: `False` - -### PASSWORD_RESET_CONFIRM_RETYPE - -If `True`, you need to pass `re_new_password` to `/password/reset/confirm/` -endpoint in order to validate password equality. - -**Default**: `False` - -### LOGOUT_ON_PASSWORD_CHANGE - -If `True`, setting new password will logout the user. - -**Default**: `False` - -### PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND - -If `True`, posting a non-existent `email` to `/password/reset/` will return -a `HTTP_400_BAD_REQUEST` response with an `EMAIL_NOT_FOUND` error message -('User with given email does not exist.'). - -If `False` (default), the `/password/reset/` endpoint will always return -a `HTTP_204_NO_CONTENT` response. - -Please note that setting this to `True` will expose information whether -an email is registered in the system. - -**Default**: `False` - -### PASSWORD_VALIDATORS - -List containing [REST Framework Validator](http://www.django-rest-framework.org/api-guide/validators/) functions. -These validators are run on `/register/` and `/password/reset/confirm/`. - -**Default**: `[]` - -**Example**: `[my_validator1, my_validator2]` - -### SERIALIZERS - -This dictionary is used to update the defaults, so by providing, -let's say, one key, all the others will still be used. - -**Examples** -``` -{ - 'user': 'myapp.serializers.SpecialUserSerializer', -} -``` - -**Default**: -``` -{ - 'activation': 'djoser.serializers.ActivationSerializer', - 'login': 'djoser.serializers.LoginSerializer', - 'password_reset': 'djoser.serializers.PasswordResetSerializer', - 'password_reset_confirm': 'djoser.serializers.PasswordResetConfirmSerializer', - 'password_reset_confirm_retype': 'djoser.serializers.PasswordResetConfirmRetypeSerializer', - 'set_password': 'djoser.serializers.SetPasswordSerializer', - 'set_password_retype': 'djoser.serializers.SetPasswordRetypeSerializer', - 'set_username': 'djoser.serializers.SetUsernameSerializer', - 'set_username_retype': 'djoser.serializers.SetUsernameRetypeSerializer', - 'user_registration': 'djoser.serializers.UserRegistrationSerializer', - 'user': 'djoser.serializers.UserSerializer', - 'token': 'djoser.serializers.TokenSerializer', -} -``` - -## Emails - -There are few email templates which you may want to override: - -* `activation_email_body.txt` -* `activation_email_subject.txt` -* `password_reset_email_body.txt` -* `password_reset_email_subject.txt` - -All of them have following context: - -* `user` -* `domain` -* `site_name` -* `url` -* `uid` -* `token` -* `protocol` - -## Sample usage - -We provide a standalone test app for you to start easily, see how everything works with basic settings. It might be useful before integrating **djoser** into your backend application. - -In this extremely short tutorial we are going to mimic the simplest flow: register user, log in and log out. We will also check resource access on each consecutive step. Let's go! - -* Clone repository and install **djoser** to your virtualenv: - - `$ git clone git@github.com:sunscrapers/djoser.git` - - `$ cd djoser` - - `$ pip install -e .` - -* Go to the `testproject` directory, migrate the database and start the development server: - - `$ cd testproject` - - `$ ./manage.py migrate` - - `$ ./manage.py runserver 8088` - -* Register a new user: - - `$ curl -X POST http://127.0.0.1:8088/auth/register/ --data 'username=djoser&password=djoser'` - - `{"email": "", "username": "djoser", "id":1}` - - So far, so good. We have just created a new user using REST API. - -* Let's access user's details: - - `$ curl -X GET http://127.0.0.1:8088/auth/me/` - - `{"detail": "Authentication credentials were not provided."}` - - As we can see, we cannot access user profile without logging in. Pretty obvious. - -* Let's log in: - - `curl -X POST http://127.0.0.1:8088/auth/login/ --data 'username=djoser&password=djoser'` - - `{"auth_token": "b704c9fc3655635646356ac2950269f352ea1139"}` - - We have just obtained an authorization token that we may use later in order to retrieve specific resources. - -* Let's access user's details again: - - `$ curl -X GET http://127.0.0.1:8088/auth/me/` - - `{"detail": "Authentication credentials were not provided."}` - - Access is still forbidden but let's offer the token we obtained: - - `$ curl -X GET http://127.0.0.1:8088/auth/me/ -H 'Authorization: Token b704c9fc3655635646356ac2950269f352ea1139'` - - `{"email": "", "username": "djoser", "id": 1}` - - Yay, it works! - -* Now let's log out: - - `curl -X POST http://127.0.0.1:8088/auth/logout/ -H 'Authorization: Token b704c9fc3655635646356ac2950269f352ea1139'` - - And try access user profile again: - - `$ curl -X GET http://127.0.0.1:8088/auth/me/ -H 'Authorization: Token b704c9fc3655635646356ac2950269f352ea1139'` - - `{"detail": "Invalid token"}` - - As we can see, user has been logged out successfully and the proper token has been removed. - -## Customization - -If you need to customize any serializer behaviour you can use -the DJOSER['SERIALIZERS'] setting to use your own serializer classes in the built-in views. -Or if you need to completely change the default djoser behaviour, -you can always override djoser views with your own custom ones. - -Define custom `urls` instead of reusing `djoser.urls`: - -```python -urlpatterns = patterns('', - (...), - url(r'^register/$', views.CustomRegistrationView.as_view()), -) -``` - -Define custom view/serializer (inherit from one of `djoser` class) and override necessary method/field: - -```python -class CustomRegistrationView(djoser.views.RegistrationView): - - def send_activation_email(self, *args, **kwargs): - your_custom_email_sender(*args, **kwargs) -``` - -You could check `djoser` API in source code: - -* [djoser.views](https://github.com/sunscrapers/djoser/blob/master/djoser/views.py) -* [djoser.serializers](https://github.com/sunscrapers/djoser/blob/master/djoser/serializers.py) - - -## Development +## Contributing and development To start developing on **djoser**, clone the repository: `$ git clone git@github.com:sunscrapers/djoser.git` -In order to run the tests create virtualenv, go to repo directory and then: +If you are a **pipenv** user you can quickly setup testing environment by +using Make commands: + +`$ make init` +`$ make test` + + You do not need to create virtualenv in this case - + it's automatically created for you. -`$ pip install -r requirements-test.txt` +Otherwise, if you cannot use Make commands, please create virtualenv and install +requirements manually: -`$ cd testproject` +`$ pip install django djangorestframework` +`$ pip install -r requirements.txt` -`$ ./manage.py migrate` +If you are running djoser tests on Python 2.7 you also need to install `mock` library. +`$ pip install mock # only on Python 2.7` +`$ cd testproject` `$ ./manage.py test` If you need to run tests against all supported Python and Django versions then invoke: -`$ pip install tox` - +`$ pip install tox` `$ tox` +You can also play with test project by running following commands: + +`$ ./manage.py migrate` +`$ ./manage.py runserver` + ## Similar projects List of projects related to Django, REST and authentication: diff -Nru djoser-0.5.2/requirements.txt djoser-0.6.0/requirements.txt --- djoser-0.5.2/requirements.txt 2017-01-02 11:51:40.000000000 +0000 +++ djoser-0.6.0/requirements.txt 2017-05-26 08:56:36.000000000 +0000 @@ -1,2 +1,3 @@ -Django>=1.7 -djangorestframework>=3.0.0 +-e . +djet==0.2.1 +coverage==4.3.1 diff -Nru djoser-0.5.2/setup.cfg djoser-0.6.0/setup.cfg --- djoser-0.5.2/setup.cfg 2017-01-02 12:01:28.000000000 +0000 +++ djoser-0.6.0/setup.cfg 2017-06-02 13:32:50.000000000 +0000 @@ -1,5 +1,4 @@ [egg_info] tag_build = tag_date = 0 -tag_svn_revision = 0 diff -Nru djoser-0.5.2/setup.py djoser-0.6.0/setup.py --- djoser-0.5.2/setup.py 2017-01-02 11:51:40.000000000 +0000 +++ djoser-0.6.0/setup.py 2017-06-02 13:13:09.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/env python -import io import os +from io import open from setuptools import setup @@ -9,7 +9,7 @@ import pypandoc description = pypandoc.convert('README.md', 'rst') except (IOError, ImportError): - description = io.open('README.md', encoding='utf-8').read() + description = open('README.md', encoding='utf-8').read() def get_packages(package): @@ -18,20 +18,16 @@ if os.path.exists(os.path.join(dirpath, '__init__.py'))] -def get_requirements(file_name): - return [i.strip() for i in open(file_name).readlines()] - - setup( name='djoser', - version='0.5.2', + version='0.6.0', packages=get_packages('djoser'), license='MIT', author='SUNSCRAPERS', description='REST version of Django authentication system.', author_email='info@sunscrapers.com', long_description=description, - install_requires=get_requirements('requirements.txt'), + install_requires=[], include_package_data=True, url='https://github.com/sunscrapers/djoser', classifiers=[