[Python-modules-commits] [djoser] 01/01: New upstream version 0.7.0

Michael Fladischer fladi at moszumanska.debian.org
Tue Sep 12 17:18:35 UTC 2017


This is an automated email from the git hooks/post-receive script.

fladi pushed a commit to branch upstream
in repository djoser.

commit ea6121a9dcbd136ddba0cda25827cbc4ac309bef
Author: Michael Fladischer <FladischerMichael at fladi.at>
Date:   Tue Sep 12 18:30:38 2017 +0200

    New upstream version 0.7.0
---
 PKG-INFO                                        |  99 ++++++++------
 README.md                                       |  71 -----------
 README.rst                                      |  94 ++++++++++++++
 djoser.egg-info/PKG-INFO                        |  99 ++++++++------
 djoser.egg-info/SOURCES.txt                     |   9 +-
 djoser/compat.py                                |  20 +++
 djoser/conf.py                                  | 135 ++++++++++++++++++++
 djoser/constants.py                             |   6 +
 djoser/serializers.py                           | 163 ++++++++++++++----------
 djoser/settings.py                              |  65 ----------
 djoser/templates/activation_email_body.html     |  19 +++
 djoser/templates/activation_email_body.txt      |   2 +-
 djoser/templates/confirmation_email_body.html   |  12 ++
 djoser/templates/password_reset_email_body.html |  17 +++
 djoser/urls/__init__.py                         |   2 +
 djoser/urls/authtoken.py                        |   6 +-
 djoser/urls/base.py                             |  22 +++-
 djoser/utils.py                                 |  48 ++++---
 djoser/views.py                                 | 111 ++++++++--------
 requirements.txt                                |   5 +
 setup.py                                        |  19 ++-
 21 files changed, 659 insertions(+), 365 deletions(-)

diff --git a/PKG-INFO b/PKG-INFO
index a1cea92..e4ad509 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,82 +1,105 @@
 Metadata-Version: 1.1
 Name: djoser
-Version: 0.6.0
+Version: 0.7.0
 Summary: REST version of Django authentication system.
 Home-page: https://github.com/sunscrapers/djoser
 Author: SUNSCRAPERS
 Author-email: info at sunscrapers.com
 License: MIT
-Description: # djoser
+Description: ======
+        djoser
+        ======
         
-        [![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)
+        .. image:: https://img.shields.io/pypi/v/djoser.svg
+          :target: https://pypi.org/project/djoser
         
-        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/)
+        .. image:: https://img.shields.io/travis/sunscrapers/djoser.svg
+          :target: https://travis-ci.org/sunscrapers/djoser
+        
+        .. image:: https://img.shields.io/codecov/c/github/sunscrapers/djoser.svg
+          :target: https://codecov.io/gh/sunscrapers/djoser
+        
+        .. image:: https://img.shields.io/scrutinizer/g/sunscrapers/djoser.svg
+          :target: https://scrutinizer-ci.com/g/sunscrapers/djoser
+        
+        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/).
+        reset and account activation. It works with `custom user model <https://docs.djangoproject.com/en/dev/topics/auth/customizing/>`_.
         
-        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)
+        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.
         
-        Developed by [SUNSCRAPERS](http://sunscrapers.com/) with passion & patience.
+        Developed by `SUNSCRAPERS <http://sunscrapers.com/>`_ with passion & patience.
         
         
-        ## Documentation
+        Documentation
+        =============
         
         Documentation is available to study at
-        [http://djoser.readthedocs.io](http://djoser.readthedocs.io) and in
-        `docs` directory.
+        `http://djoser.readthedocs.io <http://djoser.readthedocs.io>`_ and in
+        ``docs`` directory.
         
-        ## Contributing and development
+        Contributing and development
+        ============================
         
         To start developing on **djoser**, clone the repository:
         
-        `$ git clone git at github.com:sunscrapers/djoser.git`
+        .. code-block:: bash
+        
+            $ git clone git at github.com:sunscrapers/djoser.git
         
         If you are a **pipenv** user you can quickly setup testing environment by
         using Make commands:
         
-        `$ make init`  
-        `$ make test`
+        .. code-block:: bash
         
-            You do not need to create virtualenv in this case -
-            it's automatically created for you.
+            $ make init
+            $ make test
         
         Otherwise, if you cannot use Make commands, please create virtualenv and install
-        requirements manually:  
+        requirements manually:
         
-        `$ pip install django djangorestframework`  
-        `$ pip install -r requirements.txt`
+        .. code-block:: bash
         
-        If you are running djoser tests on Python 2.7 you also need to install `mock` library.
+            $ pip install django djangorestframework
+            $ pip install -r requirements.txt
         
-        `$ pip install mock  # only on Python 2.7`  
-        `$ cd testproject`  
-        `$ ./manage.py test`
+        If you are running djoser tests on Python 2.7 you also need to install **mock** library.
+        
+        .. code-block:: bash
+        
+            $ 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`  
-        `$ tox`
+        .. code-block:: bash
+        
+            $ pip install tox
+            $ tox
         
         You can also play with test project by running following commands:
         
-        `$ ./manage.py migrate`  
-        `$ ./manage.py runserver`
+        .. code-block:: bash
+        
+            $ ./manage.py migrate
+            $ ./manage.py runserver
         
-        ## Similar projects
+        Similar projects
+        ================
         
         List of projects related to Django, REST and authentication:
         
-        - [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)
+        - `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 --git a/README.md b/README.md
deleted file mode 100644
index 9aff5b0..0000000
--- a/README.md
+++ /dev/null
@@ -1,71 +0,0 @@
-# djoser
-
-[![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](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/).
-
-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.
-
-Developed by [SUNSCRAPERS](http://sunscrapers.com/) with passion & patience.
-
-
-## Documentation
-
-Documentation is available to study at
-[http://djoser.readthedocs.io](http://djoser.readthedocs.io) and in
-`docs` directory.
-
-## Contributing and development
-
-To start developing on **djoser**, clone the repository:
-
-`$ git clone git at github.com:sunscrapers/djoser.git`
-
-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.
-
-Otherwise, if you cannot use Make commands, please create virtualenv and install
-requirements manually:  
-
-`$ pip install django djangorestframework`  
-`$ pip install -r requirements.txt`
-
-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`  
-`$ 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:
-
-- [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)
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..7af4ce9
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,94 @@
+======
+djoser
+======
+
+.. image:: https://img.shields.io/pypi/v/djoser.svg
+  :target: https://pypi.org/project/djoser
+
+.. image:: https://img.shields.io/travis/sunscrapers/djoser.svg
+  :target: https://travis-ci.org/sunscrapers/djoser
+
+.. image:: https://img.shields.io/codecov/c/github/sunscrapers/djoser.svg
+  :target: https://codecov.io/gh/sunscrapers/djoser
+
+.. image:: https://img.shields.io/scrutinizer/g/sunscrapers/djoser.svg
+  :target: https://scrutinizer-ci.com/g/sunscrapers/djoser
+
+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/>`_.
+
+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.
+
+Developed by `SUNSCRAPERS <http://sunscrapers.com/>`_ with passion & patience.
+
+
+Documentation
+=============
+
+Documentation is available to study at
+`http://djoser.readthedocs.io <http://djoser.readthedocs.io>`_ and in
+``docs`` directory.
+
+Contributing and development
+============================
+
+To start developing on **djoser**, clone the repository:
+
+.. code-block:: bash
+
+    $ git clone git at github.com:sunscrapers/djoser.git
+
+If you are a **pipenv** user you can quickly setup testing environment by
+using Make commands:
+
+.. code-block:: bash
+
+    $ make init
+    $ make test
+
+Otherwise, if you cannot use Make commands, please create virtualenv and install
+requirements manually:
+
+.. code-block:: bash
+
+    $ pip install django djangorestframework
+    $ pip install -r requirements.txt
+
+If you are running djoser tests on Python 2.7 you also need to install **mock** library.
+
+.. code-block:: bash
+
+    $ 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:
+
+.. code-block:: bash
+
+    $ pip install tox
+    $ tox
+
+You can also play with test project by running following commands:
+
+.. code-block:: bash
+
+    $ ./manage.py migrate
+    $ ./manage.py runserver
+
+Similar projects
+================
+
+List of projects related to Django, REST and authentication:
+
+- `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>`_
diff --git a/djoser.egg-info/PKG-INFO b/djoser.egg-info/PKG-INFO
index a1cea92..e4ad509 100644
--- a/djoser.egg-info/PKG-INFO
+++ b/djoser.egg-info/PKG-INFO
@@ -1,82 +1,105 @@
 Metadata-Version: 1.1
 Name: djoser
-Version: 0.6.0
+Version: 0.7.0
 Summary: REST version of Django authentication system.
 Home-page: https://github.com/sunscrapers/djoser
 Author: SUNSCRAPERS
 Author-email: info at sunscrapers.com
 License: MIT
-Description: # djoser
+Description: ======
+        djoser
+        ======
         
-        [![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)
+        .. image:: https://img.shields.io/pypi/v/djoser.svg
+          :target: https://pypi.org/project/djoser
         
-        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/)
+        .. image:: https://img.shields.io/travis/sunscrapers/djoser.svg
+          :target: https://travis-ci.org/sunscrapers/djoser
+        
+        .. image:: https://img.shields.io/codecov/c/github/sunscrapers/djoser.svg
+          :target: https://codecov.io/gh/sunscrapers/djoser
+        
+        .. image:: https://img.shields.io/scrutinizer/g/sunscrapers/djoser.svg
+          :target: https://scrutinizer-ci.com/g/sunscrapers/djoser
+        
+        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/).
+        reset and account activation. It works with `custom user model <https://docs.djangoproject.com/en/dev/topics/auth/customizing/>`_.
         
-        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)
+        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.
         
-        Developed by [SUNSCRAPERS](http://sunscrapers.com/) with passion & patience.
+        Developed by `SUNSCRAPERS <http://sunscrapers.com/>`_ with passion & patience.
         
         
-        ## Documentation
+        Documentation
+        =============
         
         Documentation is available to study at
-        [http://djoser.readthedocs.io](http://djoser.readthedocs.io) and in
-        `docs` directory.
+        `http://djoser.readthedocs.io <http://djoser.readthedocs.io>`_ and in
+        ``docs`` directory.
         
-        ## Contributing and development
+        Contributing and development
+        ============================
         
         To start developing on **djoser**, clone the repository:
         
-        `$ git clone git at github.com:sunscrapers/djoser.git`
+        .. code-block:: bash
+        
+            $ git clone git at github.com:sunscrapers/djoser.git
         
         If you are a **pipenv** user you can quickly setup testing environment by
         using Make commands:
         
-        `$ make init`  
-        `$ make test`
+        .. code-block:: bash
         
-            You do not need to create virtualenv in this case -
-            it's automatically created for you.
+            $ make init
+            $ make test
         
         Otherwise, if you cannot use Make commands, please create virtualenv and install
-        requirements manually:  
+        requirements manually:
         
-        `$ pip install django djangorestframework`  
-        `$ pip install -r requirements.txt`
+        .. code-block:: bash
         
-        If you are running djoser tests on Python 2.7 you also need to install `mock` library.
+            $ pip install django djangorestframework
+            $ pip install -r requirements.txt
         
-        `$ pip install mock  # only on Python 2.7`  
-        `$ cd testproject`  
-        `$ ./manage.py test`
+        If you are running djoser tests on Python 2.7 you also need to install **mock** library.
+        
+        .. code-block:: bash
+        
+            $ 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`  
-        `$ tox`
+        .. code-block:: bash
+        
+            $ pip install tox
+            $ tox
         
         You can also play with test project by running following commands:
         
-        `$ ./manage.py migrate`  
-        `$ ./manage.py runserver`
+        .. code-block:: bash
+        
+            $ ./manage.py migrate
+            $ ./manage.py runserver
         
-        ## Similar projects
+        Similar projects
+        ================
         
         List of projects related to Django, REST and authentication:
         
-        - [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)
+        - `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 --git a/djoser.egg-info/SOURCES.txt b/djoser.egg-info/SOURCES.txt
index c1c55bd..80e4484 100644
--- a/djoser.egg-info/SOURCES.txt
+++ b/djoser.egg-info/SOURCES.txt
@@ -1,11 +1,13 @@
 MANIFEST.in
-README.md
+README.rst
 requirements.txt
+setup.cfg
 setup.py
 djoser/__init__.py
+djoser/compat.py
+djoser/conf.py
 djoser/constants.py
 djoser/serializers.py
-djoser/settings.py
 djoser/signals.py
 djoser/utils.py
 djoser/views.py
@@ -13,10 +15,13 @@ djoser.egg-info/PKG-INFO
 djoser.egg-info/SOURCES.txt
 djoser.egg-info/dependency_links.txt
 djoser.egg-info/top_level.txt
+djoser/templates/activation_email_body.html
 djoser/templates/activation_email_body.txt
 djoser/templates/activation_email_subject.txt
+djoser/templates/confirmation_email_body.html
 djoser/templates/confirmation_email_body.txt
 djoser/templates/confirmation_email_subject.txt
+djoser/templates/password_reset_email_body.html
 djoser/templates/password_reset_email_body.txt
 djoser/templates/password_reset_email_subject.txt
 djoser/urls/__init__.py
diff --git a/djoser/compat.py b/djoser/compat.py
new file mode 100644
index 0000000..1f00eef
--- /dev/null
+++ b/djoser/compat.py
@@ -0,0 +1,20 @@
+from djoser.conf import settings
+
+try:
+    from django.contrib.auth.password_validation import validate_password
+except ImportError:
+    from password_validation import validate_password
+
+__all__ = ['settings', 'validate_password']
+
+
+def get_user_email(user):
+    email_field_name = get_user_email_field_name(user)
+    return getattr(user, email_field_name, None)
+
+
+def get_user_email_field_name(user):
+    try:  # Assume we are Django >= 1.11
+        return user.get_email_field_name()
+    except AttributeError:  # we are using Django < 1.11
+        return settings.USER_EMAIL_FIELD_NAME
diff --git a/djoser/conf.py b/djoser/conf.py
new file mode 100644
index 0000000..61f7a9b
--- /dev/null
+++ b/djoser/conf.py
@@ -0,0 +1,135 @@
+import warnings
+
+from django.conf import settings as django_settings
+from django.core.exceptions import ImproperlyConfigured
+from django.test.signals import setting_changed
+from django.utils import six
+from django.utils.functional import LazyObject
+from django.utils.module_loading import import_string
+
+
+DJOSER_SETTINGS_NAMESPACE = 'DJOSER'
+
+
+class ObjDict(dict):
+    def __getattribute__(self, item):
+        try:
+            if isinstance(self[item], str):
+                self[item] = import_string(self[item])
+            value = self[item]
+        except KeyError:
+            value = super(ObjDict, self).__getattribute__(item)
+
+        return value
+
+
+default_settings = {
+    'USE_HTML_EMAIL_TEMPLATES': False,
+    'SEND_ACTIVATION_EMAIL': False,
+    'SEND_CONFIRMATION_EMAIL': False,
+    'SET_PASSWORD_RETYPE': False,
+    'SET_USERNAME_RETYPE': False,
+    'PASSWORD_RESET_CONFIRM_RETYPE': False,
+    'PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND': False,
+    'ROOT_VIEW_URLS_MAPPING': {},
+    'PASSWORD_VALIDATORS': [],
+    'TOKEN_MODEL': 'rest_framework.authtoken.models.Token',
+    'SERIALIZERS': ObjDict({
+        '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',
+    }),
+    'LOGOUT_ON_PASSWORD_CHANGE': False,
+    'USER_EMAIL_FIELD_NAME': 'email',
+}
+
+SETTINGS_TO_IMPORT = ['TOKEN_MODEL']
+
+
+class Settings(object):
+    def __init__(self, default_settings, explicit_overriden_settings=None):
+        if explicit_overriden_settings is None:
+            explicit_overriden_settings = {}
+
+        overriden_settings = getattr(
+            django_settings, DJOSER_SETTINGS_NAMESPACE, {}
+        ) or explicit_overriden_settings
+
+        self._load_default_settings()
+        self._override_settings(overriden_settings)
+        self._init_settings_to_import()
+
+    def _load_default_settings(self):
+        for setting_name, setting_value in six.iteritems(default_settings):
+            if setting_name.isupper():
+                setattr(self, setting_name, setting_value)
+
+    def _override_settings(self, overriden_settings):
+        for setting_name, setting_value in six.iteritems(overriden_settings):
+            value = setting_value
+            if isinstance(setting_value, dict):
+                value = getattr(self, setting_name, {})
+                value.update(ObjDict(setting_value))
+            setattr(self, setting_name, value)
+
+    def _init_settings_to_import(self):
+        for setting_name in SETTINGS_TO_IMPORT:
+            value = getattr(self, setting_name)
+            if isinstance(value, str):
+                setattr(self, setting_name, import_string(value))
+
+
+class LazySettings(LazyObject):
+    def _setup(self, explicit_overriden_settings=None):
+        self._wrapped = Settings(default_settings, explicit_overriden_settings)
+
+    def get(self, key):
+        """
+        This function is here only to provide backwards compatibility in
+        case anyone uses old settings interface.
+        It is strongly encouraged to use dot notation.
+        """
+        warnings.warn(
+            'The settings.get(key) is superseded by the dot attribute access.',
+            PendingDeprecationWarning
+        )
+        try:
+            return getattr(self, key)
+        except AttributeError:
+            raise ImproperlyConfigured('Missing settings: {}[\'{}\']'.format(
+                DJOSER_SETTINGS_NAMESPACE, key)
+            )
+
+
+settings = LazySettings()
+
+
+def reload_djoser_settings(*args, **kwargs):
+    global settings
+    setting, value = kwargs['setting'], kwargs['value']
+    if setting == DJOSER_SETTINGS_NAMESPACE:
+        settings._setup(explicit_overriden_settings=value)
+
+
+setting_changed.connect(reload_djoser_settings)
diff --git a/djoser/constants.py b/djoser/constants.py
index a565070..9c8b8ab 100644
--- a/djoser/constants.py
+++ b/djoser/constants.py
@@ -1,5 +1,6 @@
 from django.utils.translation import ugettext_lazy as _
 
+
 INVALID_CREDENTIALS_ERROR = _('Unable to login with provided credentials.')
 INACTIVE_ACCOUNT_ERROR = _('User account is disabled.')
 INVALID_TOKEN_ERROR = _('Invalid token for given user.')
@@ -10,3 +11,8 @@ 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.')
+USER_WITHOUT_EMAIL_FIELD_ERROR = _(
+    'User model does not contain specified email field. '
+    'Please see http://djoser.readthedocs.io/en/latest/settings.html#'
+    'USER_EMAIL_FIELD_NAME for more details.'
+)
diff --git a/djoser/serializers.py b/djoser/serializers.py
index 570a4fc..0d71ee6 100644
--- a/djoser/serializers.py
+++ b/djoser/serializers.py
@@ -1,12 +1,13 @@
 from django.contrib.auth import authenticate, get_user_model
 from django.db import IntegrityError, transaction
-from django.utils import six
-from django.utils.module_loading import import_string
 
 from rest_framework import exceptions, serializers
-from rest_framework.authtoken.models import Token
 
-from . import constants, utils, settings
+from djoser import constants, utils
+from djoser.compat import (
+    get_user_email, get_user_email_field_name, validate_password
+)
+from djoser.conf import settings
 
 User = get_user_model()
 
@@ -18,16 +19,22 @@ class UserSerializer(serializers.ModelSerializer):
             User._meta.pk.name,
             User.USERNAME_FIELD,
         )
-        read_only_fields = (
-            User.USERNAME_FIELD,
-        )
+        read_only_fields = (User.USERNAME_FIELD,)
+
+    def update(self, instance, validated_data):
+        email_field = get_user_email_field_name(User)
+        if settings.SEND_ACTIVATION_EMAIL and email_field in validated_data:
+            instance_email = get_user_email(instance)
+            if instance_email != validated_data[email_field]:
+                instance.is_active = False
+                instance.save(update_fields=['is_active'])
+        return super(UserSerializer, self).update(instance, validated_data)
 
 
 class UserRegistrationSerializer(serializers.ModelSerializer):
     password = serializers.CharField(
         style={'input_type': 'password'},
-        write_only=True,
-        validators=settings.get('PASSWORD_VALIDATORS')
+        write_only=True
     )
 
     default_error_messages = {
@@ -40,6 +47,10 @@ class UserRegistrationSerializer(serializers.ModelSerializer):
             User.USERNAME_FIELD, User._meta.pk.name, 'password',
         )
 
+    def validate_password(self, value):
+        validate_password(value)
+        return value
+
     def create(self, validated_data):
         try:
             user = self.perform_create(validated_data)
@@ -53,7 +64,7 @@ class UserRegistrationSerializer(serializers.ModelSerializer):
     def perform_create(self, validated_data):
         with transaction.atomic():
             user = User.objects.create_user(**validated_data)
-            if settings.get('SEND_ACTIVATION_EMAIL'):
+            if settings.SEND_ACTIVATION_EMAIL:
                 user.is_active = False
                 user.save(update_fields=['is_active'])
         return user
@@ -72,24 +83,32 @@ class LoginSerializer(serializers.Serializer):
     def __init__(self, *args, **kwargs):
         super(LoginSerializer, self).__init__(*args, **kwargs)
         self.user = None
-        self.fields[User.USERNAME_FIELD] = serializers.CharField(required=False)
+        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')
         )
-        if self.user:
-            if not self.user.is_active:
-                raise serializers.ValidationError(
-                    self.error_messages['inactive_account']
-                )
-            return attrs
-        else:
+
+        self._validate_user_exists(self.user)
+        self._validate_user_is_active(self.user)
+        return attrs
+
+    def _validate_user_exists(self, user):
+        if not user:
             raise serializers.ValidationError(
                 self.error_messages['invalid_credentials']
             )
 
+    def _validate_user_is_active(self, user):
+        if not user.is_active:
+            raise serializers.ValidationError(
+                self.error_messages['inactive_account']
+            )
+
 
 class PasswordResetSerializer(serializers.Serializer):
     email = serializers.EmailField()
@@ -99,9 +118,11 @@ class PasswordResetSerializer(serializers.Serializer):
     }
 
     def validate_email(self, value):
-        if settings.get('PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND') and \
-                not self.context['view'].get_users(value):
-            raise serializers.ValidationError(self.error_messages['email_not_found'])
+        users = self.context['view'].get_users(value)
+        if settings.PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND and not users:
+            raise serializers.ValidationError(
+                self.error_messages['email_not_found']
+            )
         return value
 
 
@@ -118,15 +139,20 @@ class UidAndTokenSerializer(serializers.Serializer):
         try:
             uid = utils.decode_uid(value)
             self.user = User.objects.get(pk=uid)
-        except (User.DoesNotExist, ValueError, TypeError, OverflowError) as error:
-            raise serializers.ValidationError(self.error_messages['invalid_uid'])
+        except (User.DoesNotExist, ValueError, TypeError, OverflowError):
+            raise serializers.ValidationError(
+                self.error_messages['invalid_uid']
+            )
         return value
 
     def validate(self, attrs):
         attrs = super(UidAndTokenSerializer, self).validate(attrs)
-        if not self.context['view'].token_generator.check_token(self.user, attrs['token']):
-            raise serializers.ValidationError(self.error_messages['invalid_token'])
-        return attrs
+        is_token_valid = self.context['view'].token_generator.check_token(
+            self.user, attrs['token']
+        )
+        if is_token_valid:
+            return attrs
+        raise serializers.ValidationError(self.error_messages['invalid_token'])
 
 
 class ActivationSerializer(UidAndTokenSerializer):
@@ -136,14 +162,17 @@ class ActivationSerializer(UidAndTokenSerializer):
 
     def validate(self, attrs):
         attrs = super(ActivationSerializer, self).validate(attrs)
-        if self.user.is_active:
-            raise exceptions.PermissionDenied(self.error_messages['stale_token'])
-        return attrs
+        if not self.user.is_active:
+            return attrs
+        raise exceptions.PermissionDenied(self.error_messages['stale_token'])
 
 
 class PasswordSerializer(serializers.Serializer):
-    new_password = serializers.CharField(style={'input_type': 'password'},
-                                         validators=settings.get('PASSWORD_VALIDATORS'))
+    new_password = serializers.CharField(style={'input_type': 'password'})
+
+    def validate_new_password(self, value):
+        validate_password(value)
+        return value
 
 
 class PasswordRetypeSerializer(PasswordSerializer):
@@ -155,9 +184,11 @@ class PasswordRetypeSerializer(PasswordSerializer):
 
     def validate(self, attrs):
         attrs = super(PasswordRetypeSerializer, self).validate(attrs)
-        if attrs['new_password'] != attrs['re_new_password']:
-            raise serializers.ValidationError(self.error_messages['password_mismatch'])
-        return attrs
+        if attrs['new_password'] == attrs['re_new_password']:
+            return attrs
+        raise serializers.ValidationError(
+            self.error_messages['password_mismatch']
+        )
 
 
 class CurrentPasswordSerializer(serializers.Serializer):
@@ -168,28 +199,35 @@ class CurrentPasswordSerializer(serializers.Serializer):
     }
 
     def validate_current_password(self, value):
-        if not self.context['request'].user.check_password(value):
-            raise serializers.ValidationError(self.error_messages['invalid_password'])
-        return value
+        is_password_valid = self.context['request'].user.check_password(value)
+        if is_password_valid:
+            return value
+        raise serializers.ValidationError(
+            self.error_messages['invalid_password']
+        )
 
 
 class SetPasswordSerializer(PasswordSerializer, CurrentPasswordSerializer):
     pass
 
 
-class SetPasswordRetypeSerializer(PasswordRetypeSerializer, CurrentPasswordSerializer):
+class SetPasswordRetypeSerializer(PasswordRetypeSerializer,
+                                  CurrentPasswordSerializer):
     pass
 
 
-class PasswordResetConfirmSerializer(UidAndTokenSerializer, PasswordSerializer):
+class PasswordResetConfirmSerializer(UidAndTokenSerializer,
+                                     PasswordSerializer):
     pass
 
 
-class PasswordResetConfirmRetypeSerializer(UidAndTokenSerializer, PasswordRetypeSerializer):
+class PasswordResetConfirmRetypeSerializer(UidAndTokenSerializer,
+                                           PasswordRetypeSerializer):
     pass
 
 
-class SetUsernameSerializer(serializers.ModelSerializer, CurrentPasswordSerializer):
+class SetUsernameSerializer(serializers.ModelSerializer,
+                            CurrentPasswordSerializer):
 
     class Meta(object):
         model = User
@@ -199,14 +237,21 @@ class SetUsernameSerializer(serializers.ModelSerializer, CurrentPasswordSerializ
         )
 
     def __init__(self, *args, **kwargs):
+        """
+        This method should probably be replaced by a better solution.
+        Its purpose is to replace USERNAME_FIELD with 'new_' + USERNAME_FIELD
+        so that the new field is being assigned a field for USERNAME_FIELD
+        """
         super(SetUsernameSerializer, self).__init__(*args, **kwargs)
-        self.fields['new_' + User.USERNAME_FIELD] = self.fields[User.USERNAME_FIELD]
-        del self.fields[User.USERNAME_FIELD]
+        username_field = User.USERNAME_FIELD
+        self.fields['new_' + username_field] = self.fields.pop(username_field)
 
 
 class SetUsernameRetypeSerializer(SetUsernameSerializer):
     default_error_messages = {
-        'username_mismatch': constants.USERNAME_MISMATCH_ERROR.format(User.USERNAME_FIELD),
+        'username_mismatch': constants.USERNAME_MISMATCH_ERROR.format(
+            User.USERNAME_FIELD
+        ),
     }
 
     def __init__(self, *args, **kwargs):
@@ -217,7 +262,11 @@ class SetUsernameRetypeSerializer(SetUsernameSerializer):
         attrs = super(SetUsernameRetypeSerializer, self).validate(attrs)
         new_username = attrs[User.USERNAME_FIELD]
         if new_username != attrs['re_new_' + User.USERNAME_FIELD]:
-            raise serializers.ValidationError(self.error_messages['username_mismatch'].format(User.USERNAME_FIELD))
+            raise serializers.ValidationError(
+                self.error_messages['username_mismatch'].format(
+                    User.USERNAME_FIELD
+                )
+            )
         return attrs
 
 
@@ -225,29 +274,7 @@ class TokenSerializer(serializers.ModelSerializer):
     auth_token = serializers.CharField(source='key')
 
     class Meta:
-        model = Token
+        model = settings.TOKEN_MODEL
... 658 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/djoser.git



More information about the Python-modules-commits mailing list