././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.3979297 djoser-2.1.0/LICENSE0000644000000000000000000000207300000000000010676 0ustar00The MIT License (MIT) Copyright (c) 2013-2019 SUNSCRAPERS Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1603449460.355233 djoser-2.1.0/README.rst0000644000000000000000000001117100000000000011357 0ustar00====== djoser ====== .. image:: https://img.shields.io/pypi/v/djoser.svg :target: https://pypi.org/project/djoser .. image:: https://img.shields.io/travis/sunscrapers/djoser/master.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://api.codacy.com/project/badge/Grade/c9bf80318d2741e5bb63912a5e0b32dc :alt: Codacy Badge :target: https://app.codacy.com/app/dekoza/djoser?utm_source=github.com&utm_medium=referral&utm_content=sunscrapers/djoser&utm_campaign=Badge_Grade_Dashboard .. image:: https://img.shields.io/pypi/dm/djoser :target: https://img.shields.io/pypi/dm/djoser 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. .. image:: https://asciinema.org/a/94J4eG2tSBD2iEfF30a6vGtXw.png :target: https://asciinema.org/a/94J4eG2tSBD2iEfF30a6vGtXw Requirements ============ To be able to run **djoser** you have to meet following requirements: - Python (3.6, 3.7, 3.8, 3.9) - Django (2.2, 3.1) - Django REST Framework 3.11.1 If you need to support other versions, please use djoser<2. Installation ============ Simply install using ``pip``: .. code-block:: bash $ pip install djoser And continue with the steps described at `configuration `_ guide. Documentation ============= Documentation is available to study at `https://djoser.readthedocs.io `_ and in ``docs`` directory. Contributing and development ============================ To start developing on **djoser**, clone the repository: .. code-block:: bash $ git clone git@github.com:sunscrapers/djoser.git We use `poetry `_ as dependency management and packaging tool. .. code-block:: bash $ cd djoser $ poetry install -E test This will create a virtualenv with all development dependencies. To run the test just type: .. code-block:: bash $ poetry run py.test testproject We also preapred a convenient ``Makefile`` to automate commands above: .. code-block:: bash $ make init $ make test To activate the virtual environment run .. code-block:: bash $ poetry shell Without poetry -------------- New versions of ``pip`` can use ``pyproject.toml`` to build the package and install its dependencies. .. code-block:: bash $ pip install .[test] .. code-block:: bash $ cd testproject $ ./manage.py test Tox --- If you need to run tests against all supported Python and Django versions then invoke: .. code-block:: bash $ poetry run tox -p all Example project --------------- You can also play with test project by running following commands: .. code-block:: bash $ make migrate $ make runserver Commiting your code ------------------- Before sending patches please make sure you have `pre-commit `_ activated in your local git repository: .. code-block:: bash $ pre-commit install This will ensure that your code is cleaned before you commit it. Some steps (like black) automatically fix issues but the show their status as FAILED. Just inspect if eveything is OK, git-add the files and retry the commit. Other tools (like flake8) require you to manually fix the issues. Similar projects ================ List of projects related to Django, REST and authentication: - `django-rest-framework-simplejwt `_ - `django-oauth-toolkit `_ - `django-rest-auth `_ (not maintained) - `django-rest-framework-digestauth `_ (not maintained) Please, keep in mind that while using custom authentication and TokenCreateSerializer validation, there is a path that **ignores intentional return of None** from authenticate() and try to find User using parameters. Probably, that will be changed in the future. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.3993125 djoser-2.1.0/djoser/.codacy.yml0000644000000000000000000000006200000000000013216 0ustar00exclude_paths: - "docs/**" - "testproject/**" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.3994265 djoser-2.1.0/djoser/__init__.py0000644000000000000000000000024700000000000013271 0ustar00try: import importlib.metadata as importlib_metadata except ModuleNotFoundError: import importlib_metadata __version__ = importlib_metadata.version(__name__) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1603274433.399533 djoser-2.1.0/djoser/compat.py0000644000000000000000000000041300000000000013010 0ustar00from djoser.conf import settings __all__ = ["settings"] 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): return user.get_email_field_name() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.3996687 djoser-2.1.0/djoser/conf.py0000644000000000000000000001462500000000000012464 0ustar00from django.apps import apps from django.conf import settings as django_settings from django.test.signals import setting_changed from django.utils.functional import LazyObject from django.utils.module_loading import import_string DJOSER_SETTINGS_NAMESPACE = "DJOSER" auth_module, user_model = django_settings.AUTH_USER_MODEL.rsplit(".", 1) User = apps.get_model(auth_module, user_model) class ObjDict(dict): def __getattribute__(self, item): try: val = self[item] if isinstance(val, str): val = import_string(val) elif isinstance(val, (list, tuple)): val = [import_string(v) if isinstance(v, str) else v for v in val] self[item] = val except KeyError: val = super(ObjDict, self).__getattribute__(item) return val default_settings = { "USER_ID_FIELD": User._meta.pk.name, "LOGIN_FIELD": User.USERNAME_FIELD, "SEND_ACTIVATION_EMAIL": False, "SEND_CONFIRMATION_EMAIL": False, "USER_CREATE_PASSWORD_RETYPE": False, "SET_PASSWORD_RETYPE": False, "PASSWORD_RESET_CONFIRM_RETYPE": False, "SET_USERNAME_RETYPE": False, "USERNAME_RESET_CONFIRM_RETYPE": False, "PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND": False, "USERNAME_RESET_SHOW_EMAIL_NOT_FOUND": False, "PASSWORD_CHANGED_EMAIL_CONFIRMATION": False, "USERNAME_CHANGED_EMAIL_CONFIRMATION": False, "TOKEN_MODEL": "rest_framework.authtoken.models.Token", "SERIALIZERS": ObjDict( { "activation": "djoser.serializers.ActivationSerializer", "password_reset": "djoser.serializers.SendEmailResetSerializer", "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", "username_reset": "djoser.serializers.SendEmailResetSerializer", "username_reset_confirm": "djoser.serializers.UsernameResetConfirmSerializer", "username_reset_confirm_retype": "djoser.serializers.UsernameResetConfirmRetypeSerializer", "user_create": "djoser.serializers.UserCreateSerializer", "user_create_password_retype": "djoser.serializers.UserCreatePasswordRetypeSerializer", "user_delete": "djoser.serializers.UserDeleteSerializer", "user": "djoser.serializers.UserSerializer", "current_user": "djoser.serializers.UserSerializer", "token": "djoser.serializers.TokenSerializer", "token_create": "djoser.serializers.TokenCreateSerializer", } ), "EMAIL": ObjDict( { "activation": "djoser.email.ActivationEmail", "confirmation": "djoser.email.ConfirmationEmail", "password_reset": "djoser.email.PasswordResetEmail", "password_changed_confirmation": "djoser.email.PasswordChangedConfirmationEmail", "username_changed_confirmation": "djoser.email.UsernameChangedConfirmationEmail", "username_reset": "djoser.email.UsernameResetEmail", } ), "CONSTANTS": ObjDict({"messages": "djoser.constants.Messages"}), "LOGOUT_ON_PASSWORD_CHANGE": False, "CREATE_SESSION_ON_LOGIN": False, "SOCIAL_AUTH_TOKEN_STRATEGY": "djoser.social.token.jwt.TokenStrategy", "SOCIAL_AUTH_ALLOWED_REDIRECT_URIS": [], "HIDE_USERS": True, "PERMISSIONS": ObjDict( { "activation": ["rest_framework.permissions.AllowAny"], "password_reset": ["rest_framework.permissions.AllowAny"], "password_reset_confirm": ["rest_framework.permissions.AllowAny"], "set_password": ["djoser.permissions.CurrentUserOrAdmin"], "username_reset": ["rest_framework.permissions.AllowAny"], "username_reset_confirm": ["rest_framework.permissions.AllowAny"], "set_username": ["djoser.permissions.CurrentUserOrAdmin"], "user_create": ["rest_framework.permissions.AllowAny"], "user_delete": ["djoser.permissions.CurrentUserOrAdmin"], "user": ["djoser.permissions.CurrentUserOrAdmin"], "user_list": ["djoser.permissions.CurrentUserOrAdmin"], "token_create": ["rest_framework.permissions.AllowAny"], "token_destroy": ["rest_framework.permissions.IsAuthenticated"], } ), } SETTINGS_TO_IMPORT = ["TOKEN_MODEL", "SOCIAL_AUTH_TOKEN_STRATEGY"] class Settings: def __init__(self, default_settings, explicit_overriden_settings: dict = 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 default_settings.items(): if setting_name.isupper(): setattr(self, setting_name, setting_value) def _override_settings(self, overriden_settings: dict): for setting_name, setting_value in overriden_settings.items(): 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) 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) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.3998125 djoser-2.1.0/djoser/constants.py0000644000000000000000000000133000000000000013540 0ustar00from django.utils.translation import gettext_lazy as _ class Messages(object): INVALID_CREDENTIALS_ERROR = _("Unable to log in with provided credentials.") INACTIVE_ACCOUNT_ERROR = _("User account is disabled.") INVALID_TOKEN_ERROR = _("Invalid token for given user.") INVALID_UID_ERROR = _("Invalid user id or user doesn't exist.") STALE_TOKEN_ERROR = _("Stale token for given user.") PASSWORD_MISMATCH_ERROR = _("The two password fields didn't match.") 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.") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.3999977 djoser-2.1.0/djoser/email.py0000644000000000000000000000350500000000000012621 0ustar00from django.contrib.auth.tokens import default_token_generator from templated_mail.mail import BaseEmailMessage from djoser import utils from djoser.conf import settings class ActivationEmail(BaseEmailMessage): template_name = "email/activation.html" def get_context_data(self): # ActivationEmail can be deleted context = super().get_context_data() user = context.get("user") context["uid"] = utils.encode_uid(user.pk) context["token"] = default_token_generator.make_token(user) context["url"] = settings.ACTIVATION_URL.format(**context) return context class ConfirmationEmail(BaseEmailMessage): template_name = "email/confirmation.html" class PasswordResetEmail(BaseEmailMessage): template_name = "email/password_reset.html" def get_context_data(self): # PasswordResetEmail can be deleted context = super().get_context_data() user = context.get("user") context["uid"] = utils.encode_uid(user.pk) context["token"] = default_token_generator.make_token(user) context["url"] = settings.PASSWORD_RESET_CONFIRM_URL.format(**context) return context class PasswordChangedConfirmationEmail(BaseEmailMessage): template_name = "email/password_changed_confirmation.html" class UsernameChangedConfirmationEmail(BaseEmailMessage): template_name = "email/username_changed_confirmation.html" class UsernameResetEmail(BaseEmailMessage): template_name = "email/username_reset.html" def get_context_data(self): context = super().get_context_data() user = context.get("user") context["uid"] = utils.encode_uid(user.pk) context["token"] = default_token_generator.make_token(user) context["url"] = settings.USERNAME_RESET_CONFIRM_URL.format(**context) return context ././@PaxHeader0000000000000000000000000000003100000000000010207 xustar0025 mtime=1603443965.2944 djoser-2.1.0/djoser/locale/de/LC_MESSAGES/django.mo0000644000000000000000000000614200000000000016373 0ustar00I# &+R:r4%0 Vw+%r[j2_(~K:0-?-A?oM.+, X .s - - < %; a 4 a# h 8 :' %(site_name)s - Your account has been successfully created and activated!Account activation on %(site_name)sInvalid password.Invalid token for given user.Invalid user id or user doesn't exist.Password reset on %(site_name)sPlease go to the following page and choose a new password:Please go to the following page to activate account:Stale token for given user.Thanks for using our site!The %(site_name)s teamThe two password fields didn't match.The two {0} fields didn't match.Unable to create account.Unable to log in with provided credentials.User account is disabled.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.User with given email does not exist.You're receiving this email because you need to finish activation process on %(site_name)s.You're receiving this email because you requested a password reset for your user account at %(site_name)s.Your account has been created and is ready to use!Your username, in case you've forgotten:Project-Id-Version: djoser Report-Msgid-Bugs-To: POT-Creation-Date: 2020-01-13 17:40+0100 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: Bertram Bühner Language: de Language-Team: German Plural-Forms: nplurals=2; plural=(n > 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 2.8.0 %(site_name)s - Ihr Benutzerkonto wurde erfolgreich erstellt und aktiviert!Aktivierung des Benutzerkontos auf %(site_name)sDas Passwort ist ungültig.Das Token für diesen Benutzer ist ungültig.Die User-ID ist ungültig oder dieser Benutzer existiert nicht.Zurücksetzen des Passworts auf %(site_name)sBitte geben Sie auf der folgenden Seite ein neues Passwort ein:Bitte begeben Sie sich auf folgende Seite, um die Aktivierung abzuschließen:Das Token für diesen Benutzer ist abgelaufen.Vielen Dank für die Nutzung unserer Seite!Das Team von %(site_name)sDie beiden Passwörter stimmen nicht überein.Die beiden {0}-Felder stimmen nicht überein.Das Benutzerkonto kann nicht angelegt werden.Eine Anmeldung ist mit den angegebenen Daten nicht möglich.Dieses Benutzerkonto ist deaktiviert.Das user-model enthält kein E-Mail-Feld. Weitere Details unter http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME .Es existiert kein Benutzer mit dieser E-Mailadresse.Sie erhalten diese E-Mail, da Sie den Aktivierungsprozess auf %(site_name)s.abschließen müssen.Sie erhalten diese E-Mail, da Sie das Zurücksetzen Ihres Passworts auf %(site_name)s angefordert haben.Ihr Benutzerkonto wurde erstellt und ist freigeschaltet!Ihr Benutzername - falls Sie ihn vergessen haben - lautet:././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603369649.4654763 djoser-2.1.0/djoser/locale/de/LC_MESSAGES/django.po0000644000000000000000000001124100000000000016372 0ustar00# Copyright (C) Sunscrapers # This file is distributed under the same license as the djoser package. # # Translators: # Bertram Bühner , 2020 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: djoser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-01-13 17:40+0100\n" "Last-Translator: Bertram Bühner \n" "Language-Team: German\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: constants.py:4 msgid "Unable to log in with provided credentials." msgstr "Eine Anmeldung ist mit den angegebenen Daten nicht möglich." #: constants.py:5 msgid "User account is disabled." msgstr "Dieses Benutzerkonto ist deaktiviert." #: constants.py:6 msgid "Invalid token for given user." msgstr "Das Token für diesen Benutzer ist ungültig." #: constants.py:7 msgid "Invalid user id or user doesn't exist." msgstr "Die User-ID ist ungültig oder dieser Benutzer existiert nicht." #: constants.py:8 msgid "Stale token for given user." msgstr "Das Token für diesen Benutzer ist abgelaufen." #: constants.py:9 msgid "The two password fields didn't match." msgstr "Die beiden Passwörter stimmen nicht überein." #: constants.py:10 #, python-brace-format msgid "The two {0} fields didn't match." msgstr "Die beiden {0}-Felder stimmen nicht überein." #: constants.py:11 msgid "Invalid password." msgstr "Das Passwort ist ungültig." #: constants.py:12 msgid "User with given email does not exist." msgstr "Es existiert kein Benutzer mit dieser E-Mailadresse." #: constants.py:13 msgid "Unable to create account." msgstr "Das Benutzerkonto kann nicht angelegt werden." #: constants.py:15 msgid "" "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." msgstr "" "Das user-model enthält kein E-Mail-Feld. Weitere Details unter " "http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME " "." #: templates/email/activation.html:4 #, python-format msgid "Account activation on %(site_name)s" msgstr "Aktivierung des Benutzerkontos auf %(site_name)s" #: templates/email/activation.html:8 templates/email/activation.html:19 #, python-format msgid "" "You're receiving this email because you need to finish activation process on " "%(site_name)s." msgstr "" "Sie erhalten diese E-Mail, da Sie den Aktivierungsprozess auf %(site_name)s." "abschließen müssen." #: templates/email/activation.html:10 templates/email/activation.html:22 msgid "Please go to the following page to activate account:" msgstr "Bitte begeben Sie sich auf folgende Seite, um die Aktivierung abzuschließen:" #: templates/email/activation.html:13 templates/email/activation.html:25 #: templates/email/confirmation.html:10 templates/email/confirmation.html:18 #: templates/email/password_reset.html:14 #: templates/email/password_reset.html:26 msgid "Thanks for using our site!" msgstr "Vielen Dank für die Nutzung unserer Seite!" #: templates/email/activation.html:15 templates/email/activation.html:27 #: templates/email/confirmation.html:12 templates/email/confirmation.html:20 #: templates/email/password_reset.html:16 #: templates/email/password_reset.html:28 #, python-format msgid "The %(site_name)s team" msgstr "Das Team von %(site_name)s" #: templates/email/confirmation.html:4 #, python-format msgid "" "%(site_name)s - Your account has been successfully created and activated!" msgstr "" "%(site_name)s - Ihr Benutzerkonto wurde erfolgreich erstellt und aktiviert!" #: templates/email/confirmation.html:8 templates/email/confirmation.html:16 msgid "Your account has been created and is ready to use!" msgstr "Ihr Benutzerkonto wurde erstellt und ist freigeschaltet!" #: templates/email/password_reset.html:4 #, python-format msgid "Password reset on %(site_name)s" msgstr "Zurücksetzen des Passworts auf %(site_name)s" #: templates/email/password_reset.html:8 templates/email/password_reset.html:20 #, python-format msgid "" "You're receiving this email because you requested a password reset for your " "user account at %(site_name)s." msgstr "" "Sie erhalten diese E-Mail, da Sie das Zurücksetzen Ihres Passworts auf " "%(site_name)s angefordert haben." #: templates/email/password_reset.html:10 #: templates/email/password_reset.html:22 msgid "Please go to the following page and choose a new password:" msgstr "Bitte geben Sie auf der folgenden Seite ein neues Passwort ein:" #: templates/email/password_reset.html:12 #: templates/email/password_reset.html:24 msgid "Your username, in case you've forgotten:" msgstr "Ihr Benutzername - falls Sie ihn vergessen haben - lautet:" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603443965.3051643 djoser-2.1.0/djoser/locale/es/LC_MESSAGES/django.mo0000644000000000000000000000706100000000000016413 0ustar00I<7<t#&,:L:4.%E k+%[2jj2d(|>}:6%. T "j - ' Q M5 B !   :# 2^ ) = * '$ #L ap e a8 .  )%(site_name)s - Your account has been successfully created and activated!%(site_name)s - Your password has been successfully changed!%(site_name)s - Your username has been successfully changed!Account activation on %(site_name)sInvalid password.Invalid token for given user.Invalid user id or user doesn't exist.Password reset on %(site_name)sPlease go to the following page and choose a new password:Please go to the following page and choose a new username:Please go to the following page to activate account:Stale token for given user.Thanks for using our site!The %(site_name)s teamThe two password fields didn't match.The two {0} fields didn't match.Unable to create account.Unable to log in with provided credentials.User account is disabled.User with given email does not exist.Username reset on %(site_name)sYou're receiving this email because you need to finish activation process on %(site_name)s.You're receiving this email because you requested a password reset for your user account at %(site_name)s.You're receiving this email because you requested a username reset for your user account at %(site_name)s.Your account has been created and is ready to use!Your password has been changed!Your username has been changed!Your username, in case you've forgotten:Project-Id-Version: djoser Report-Msgid-Bugs-To: POT-Creation-Date: 2020-04-18 20:06-0300 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: Ariel Torti Language: es Language-Team: Spanish Plural-Forms: nplurals=2; plural=(n != 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 2.8.0 %(site_name)s - Su cuenta ha sido creada y activada con exito!%(site_name)s - Su contraseña ha sido cambiada con exito!%(site_name)s - Su usuario ha sido cambiado con exito!Activacion de la cuenta %(site_name)sContraseña invalida.El token del usuario no es valido.Id de usuario invalida o usuario inexistente.Reseteo de contraseña en %(site_name)sPor favor diríjase a la siguiente página para seleccionar su nueva contraseña:Por favor diríjase a la siguiente página para seleccionar su nuevo usuario:Por favor diríjase a la siguiente página para activar su cuenta:El token del usuario ha expirado.Gracias por usar nuestro sitio!El equipo de %(site_name)sEl contenido de los dos campos de contraseña no coincide.El contenido de los dos campos de {0} no coincide.No es posible crear la cuenta de usuario.No es posible iniciar sesion con las credenciales proveídas.Esta cuenta de usuario esta deshabilitada.No existe un usuario con el email dado.Reseteo de usuario en %(site_name)sUsted ha recibido este email porque necesita finalizar el proceso de activacion en %(site_name)s.Usted ha recibido este email porque solicito un cambio de contraseña para su cuenta en %(site_name)sUsted ha recibido este email porque solicito un cambio de usuario para su cuenta en %(site_name)sSu cuenta fue creada y esta lista para usarse!Su contraseña ha sido cambiada!Su usuario ha sido cambiado!Su usuario, en caso que lo haya olvidado:././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603369652.9410713 djoser-2.1.0/djoser/locale/es/LC_MESSAGES/django.po0000644000000000000000000001552100000000000016416 0ustar00# Copyright (C) Sunscrapers # This file is distributed under the same license as the djoser package. # # Translators: # Ariel Torti , 2020 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: djoser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-04-18 20:06-0300\n" "Last-Translator: Ariel Torti \n" "Language-Team: Spanish\n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: djoser/constants.py:5 msgid "Unable to log in with provided credentials." msgstr "No es posible iniciar sesion con las credenciales proveídas." #: djoser/constants.py:6 msgid "User account is disabled." msgstr "Esta cuenta de usuario esta deshabilitada." #: djoser/constants.py:7 msgid "Invalid token for given user." msgstr "El token del usuario no es valido." #: djoser/constants.py:8 msgid "Invalid user id or user doesn't exist." msgstr "Id de usuario invalida o usuario inexistente." #: djoser/constants.py:9 msgid "Stale token for given user." msgstr "El token del usuario ha expirado." #: djoser/constants.py:10 msgid "The two password fields didn't match." msgstr "El contenido de los dos campos de contraseña no coincide." #: djoser/constants.py:11 #, python-brace-format msgid "The two {0} fields didn't match." msgstr "El contenido de los dos campos de {0} no coincide." #: djoser/constants.py:12 msgid "Invalid password." msgstr "Contraseña invalida." #: djoser/constants.py:13 msgid "User with given email does not exist." msgstr "No existe un usuario con el email dado." #: djoser/constants.py:14 msgid "Unable to create account." msgstr "No es posible crear la cuenta de usuario." #: djoser/templates/email/activation.html:4 #, python-format msgid "Account activation on %(site_name)s" msgstr "Activacion de la cuenta %(site_name)s" #: djoser/templates/email/activation.html:8 #: djoser/templates/email/activation.html:19 #, python-format msgid "" "You're receiving this email because you need to finish activation process on " "%(site_name)s." msgstr "" "Usted ha recibido este email porque necesita finalizar el proceso de activacion en " "%(site_name)s." #: djoser/templates/email/activation.html:10 #: djoser/templates/email/activation.html:21 msgid "Please go to the following page to activate account:" msgstr "Por favor diríjase a la siguiente página para activar su cuenta:" #: djoser/templates/email/activation.html:13 #: djoser/templates/email/activation.html:24 #: djoser/templates/email/confirmation.html:10 #: djoser/templates/email/confirmation.html:18 #: djoser/templates/email/password_changed_confirmation.html:10 #: djoser/templates/email/password_changed_confirmation.html:18 #: djoser/templates/email/password_reset.html:14 #: djoser/templates/email/password_reset.html:26 #: djoser/templates/email/username_changed_confirmation.html:10 #: djoser/templates/email/username_changed_confirmation.html:18 #: djoser/templates/email/username_reset.html:14 #: djoser/templates/email/username_reset.html:26 msgid "Thanks for using our site!" msgstr "Gracias por usar nuestro sitio!" #: djoser/templates/email/activation.html:15 #: djoser/templates/email/activation.html:26 #: djoser/templates/email/confirmation.html:12 #: djoser/templates/email/confirmation.html:20 #: djoser/templates/email/password_changed_confirmation.html:12 #: djoser/templates/email/password_changed_confirmation.html:20 #: djoser/templates/email/password_reset.html:16 #: djoser/templates/email/password_reset.html:28 #: djoser/templates/email/username_changed_confirmation.html:12 #: djoser/templates/email/username_changed_confirmation.html:20 #: djoser/templates/email/username_reset.html:16 #: djoser/templates/email/username_reset.html:28 #, python-format msgid "The %(site_name)s team" msgstr "El equipo de %(site_name)s" #: djoser/templates/email/confirmation.html:4 #, python-format msgid "" "%(site_name)s - Your account has been successfully created and activated!" msgstr "%(site_name)s - Su cuenta ha sido creada y activada con exito!" #: djoser/templates/email/confirmation.html:8 #: djoser/templates/email/confirmation.html:16 msgid "Your account has been created and is ready to use!" msgstr "Su cuenta fue creada y esta lista para usarse!" #: djoser/templates/email/password_changed_confirmation.html:4 #, python-format msgid "%(site_name)s - Your password has been successfully changed!" msgstr "%(site_name)s - Su contraseña ha sido cambiada con exito!" #: djoser/templates/email/password_changed_confirmation.html:8 #: djoser/templates/email/password_changed_confirmation.html:16 msgid "Your password has been changed!" msgstr "Su contraseña ha sido cambiada!" #: djoser/templates/email/password_reset.html:4 #, python-format msgid "Password reset on %(site_name)s" msgstr "Reseteo de contraseña en %(site_name)s" #: djoser/templates/email/password_reset.html:8 #: djoser/templates/email/password_reset.html:20 #, python-format msgid "" "You're receiving this email because you requested a password reset for your " "user account at %(site_name)s." msgstr "" "Usted ha recibido este email porque solicito un cambio de contraseña para su " "cuenta en %(site_name)s" #: djoser/templates/email/password_reset.html:10 #: djoser/templates/email/password_reset.html:22 msgid "Please go to the following page and choose a new password:" msgstr "Por favor diríjase a la siguiente página para seleccionar su nueva contraseña:" #: djoser/templates/email/password_reset.html:12 #: djoser/templates/email/password_reset.html:24 #: djoser/templates/email/username_reset.html:12 #: djoser/templates/email/username_reset.html:24 msgid "Your username, in case you've forgotten:" msgstr "Su usuario, en caso que lo haya olvidado:" #: djoser/templates/email/username_changed_confirmation.html:4 #, python-format msgid "%(site_name)s - Your username has been successfully changed!" msgstr "%(site_name)s - Su usuario ha sido cambiado con exito!" #: djoser/templates/email/username_changed_confirmation.html:8 #: djoser/templates/email/username_changed_confirmation.html:16 msgid "Your username has been changed!" msgstr "Su usuario ha sido cambiado!" #: djoser/templates/email/username_reset.html:4 #, python-format msgid "Username reset on %(site_name)s" msgstr "Reseteo de usuario en %(site_name)s" #: djoser/templates/email/username_reset.html:8 #: djoser/templates/email/username_reset.html:20 #, python-format msgid "" "You're receiving this email because you requested a username reset for your " "user account at %(site_name)s." msgstr "" "Usted ha recibido este email porque solicito un cambio de usuario para su " "cuenta en %(site_name)s" #: djoser/templates/email/username_reset.html:10 #: djoser/templates/email/username_reset.html:22 msgid "Please go to the following page and choose a new username:" msgstr "Por favor diríjase a la siguiente página para seleccionar su nuevo usuario:" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1603443965.301035 djoser-2.1.0/djoser/locale/fr/LC_MESSAGES/django.mo0000644000000000000000000000624100000000000016412 0ustar00I# &+R:r4%0 Vw+%r[j2_(uE1&w>C38Kl@*#$ H 7` .  9 &! H C h: u ; KU %(site_name)s - Your account has been successfully created and activated!Account activation on %(site_name)sInvalid password.Invalid token for given user.Invalid user id or user doesn't exist.Password reset on %(site_name)sPlease go to the following page and choose a new password:Please go to the following page to activate account:Stale token for given user.Thanks for using our site!The %(site_name)s teamThe two password fields didn't match.The two {0} fields didn't match.Unable to create account.Unable to log in with provided credentials.User account is disabled.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.User with given email does not exist.You're receiving this email because you need to finish activation process on %(site_name)s.You're receiving this email because you requested a password reset for your user account at %(site_name)s.Your account has been created and is ready to use!Your username, in case you've forgotten:Project-Id-Version: djoser Report-Msgid-Bugs-To: POT-Creation-Date: 2019-05-14 18:40+0200 PO-Revision-Date: 2019-05-14 19:03+0200 Last-Translator: Julie Rymer Language: fr Language-Team: French Plural-Forms: nplurals=2; plural=(n > 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 2.8.0 %(site_name)s - Votre compte a été créé et activé avec succès !Activation du compte sur %(site_name)sMot de passe invalide.Le jeton d'authentification est invalide pour cet utilisateur.L'id de l'utilisateur est invalide ou cet utilisateur n'existe pas.Réinitialisation du mot de passe sur %(site_name)sMerci de cliquer sur le lien suivant pour choisir un nouveau mot de passe :Veuillez cliquer sur le lien suivant pour activer votre compte :Le jeton pour cet utilisateur est expiré.Merci d'avoir utilisé notre site !L'équipe %(site_name)sLe contenu des deux champs mot de passe est différent.Le contenu des deux champs {0} est différent.Création de compte impossible.Impossible de se connecter avec les identifiants fournis.Ce compte utilisateur est désactivé.Le modèle User ne contient pas le champ email indiqué. Veuillez consulter http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME pour plus de détails.Cette adresse email ne correspond à aucun utilisateur enregistré.Vous recevez cet email car vous devez finir le processus d'activation de votre compte sur %(site_name)s.Vous recevez cet email car vous avez demandé la réinitialisation du mot de passe de votre compte sur %(site_name)s.Votre compte a été créé et est prêt a être utilisé !Votre nom d'utilisateur, au cas où vous l'auriez oublié, est le suivant :././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4010956 djoser-2.1.0/djoser/locale/fr/LC_MESSAGES/django.po0000644000000000000000000001140300000000000016411 0ustar00# Copyright (C) Sunscrapers # This file is distributed under the same license as the djoser package. # # Translators: # Julie Rymer , 2019 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: djoser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-05-14 18:40+0200\n" "PO-Revision-Date: 2019-05-14 19:03+0200\n" "Last-Translator: Julie Rymer \n" "Language-Team: French\n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: constants.py:4 msgid "Unable to log in with provided credentials." msgstr "Impossible de se connecter avec les identifiants fournis." #: constants.py:5 msgid "User account is disabled." msgstr "Ce compte utilisateur est désactivé." #: constants.py:6 msgid "Invalid token for given user." msgstr "Le jeton d'authentification est invalide pour cet utilisateur." #: constants.py:7 msgid "Invalid user id or user doesn't exist." msgstr "L'id de l'utilisateur est invalide ou cet utilisateur n'existe pas." #: constants.py:8 msgid "Stale token for given user." msgstr "Le jeton pour cet utilisateur est expiré." #: constants.py:9 msgid "The two password fields didn't match." msgstr "Le contenu des deux champs mot de passe est différent." #: constants.py:10 #, python-brace-format msgid "The two {0} fields didn't match." msgstr "Le contenu des deux champs {0} est différent." #: constants.py:11 msgid "Invalid password." msgstr "Mot de passe invalide." #: constants.py:12 msgid "User with given email does not exist." msgstr "Cette adresse email ne correspond à aucun utilisateur enregistré." #: constants.py:13 msgid "Unable to create account." msgstr "Création de compte impossible." #: constants.py:15 msgid "" "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." msgstr "" "Le modèle User ne contient pas le champ email indiqué. Veuillez consulter " "http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME " "pour plus de détails." #: templates/email/activation.html:4 #, python-format msgid "Account activation on %(site_name)s" msgstr "Activation du compte sur %(site_name)s" #: templates/email/activation.html:8 templates/email/activation.html:19 #, python-format msgid "" "You're receiving this email because you need to finish activation process on " "%(site_name)s." msgstr "" "Vous recevez cet email car vous devez finir le processus d'activation de votre " "compte sur %(site_name)s." #: templates/email/activation.html:10 templates/email/activation.html:22 msgid "Please go to the following page to activate account:" msgstr "Veuillez cliquer sur le lien suivant pour activer votre compte :" #: templates/email/activation.html:13 templates/email/activation.html:25 #: templates/email/confirmation.html:10 templates/email/confirmation.html:18 #: templates/email/password_reset.html:14 #: templates/email/password_reset.html:26 msgid "Thanks for using our site!" msgstr "Merci d'avoir utilisé notre site !" #: templates/email/activation.html:15 templates/email/activation.html:27 #: templates/email/confirmation.html:12 templates/email/confirmation.html:20 #: templates/email/password_reset.html:16 #: templates/email/password_reset.html:28 #, python-format msgid "The %(site_name)s team" msgstr "L'équipe %(site_name)s" #: templates/email/confirmation.html:4 #, python-format msgid "" "%(site_name)s - Your account has been successfully created and activated!" msgstr "" "%(site_name)s - Votre compte a été créé et activé avec succès !" #: templates/email/confirmation.html:8 templates/email/confirmation.html:16 msgid "Your account has been created and is ready to use!" msgstr "Votre compte a été créé et est prêt a être utilisé !" #: templates/email/password_reset.html:4 #, python-format msgid "Password reset on %(site_name)s" msgstr "Réinitialisation du mot de passe sur %(site_name)s" #: templates/email/password_reset.html:8 templates/email/password_reset.html:20 #, python-format msgid "" "You're receiving this email because you requested a password reset for your " "user account at %(site_name)s." msgstr "" "Vous recevez cet email car vous avez demandé la réinitialisation du mot de " "passe de votre compte sur %(site_name)s." #: templates/email/password_reset.html:10 #: templates/email/password_reset.html:22 msgid "Please go to the following page and choose a new password:" msgstr "Merci de cliquer sur le lien suivant pour choisir un nouveau mot de passe :" #: templates/email/password_reset.html:12 #: templates/email/password_reset.html:24 msgid "Your username, in case you've forgotten:" msgstr "Votre nom d'utilisateur, au cas où vous l'auriez oublié, est le suivant :" ././@PaxHeader0000000000000000000000000000003200000000000010210 xustar0026 mtime=1603443965.29109 djoser-2.1.0/djoser/locale/ka/LC_MESSAGES/django.mo0000644000000000000000000001065100000000000016376 0ustar00I# &+R:r4%0 Vw*%q[j2^(JX,P`}{MZ s x 8 M 0 iM J Q T 8 $ b6pc%(site_name)s - Your account has been successfully created and activated!Account activation on %(site_name)sInvalid password.Invalid token for given user.Invalid user id or user doesn't exist.Password reset on %(site_name)sPlease go to the following page and choose a new password:Please go to the following page to activate account:Stale token for given user.Thanks for using our site!The %(site_name)s teamThe two password fields didn't match.The two {0} fields didn't match.Unable to create account.Unable to login with provided credentials.User account is disabled.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.User with given email does not exist.You're receiving this email because you need to finish activation process on %(site_name)s.You're receiving this email because you requested a password reset for your user account at %(site_name)s.Your account has been created and is ready to use!Your username, in case you've forgotten:Project-Id-Version: 1.4.0 Report-Msgid-Bugs-To: POT-Creation-Date: 2019-01-25 09:44+0100 PO-Revision-Date: 2019-01-29 14:25+0100 Last-Translator: Szymon Pyżalski Language: ka_GE Language-Team: http://sunscrapers.com Plural-Forms: nplurals=1; plural=0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 2.8.0 %(site_name)s - თქვენი ანგარიში წარმატებით შეიქმნილია და გააკტიურებულია.ანგარიშის აკტივაცია საიტზე %(site_name)sარასწორი პაროლი.ნიშანი ტოკენი ამ მომხმარებელისთვისსახელი არასწორია ან მომხმარებელი არ არსებობს.პაროლის აღდგენა საიტზე %(site_name)s.მოჰყევით ამ ლინკს და მიუთითეთ ახალი პაროლი:მიჰყევით ამ ლინკს რათა გაააკტიუროთ ანგარიში:ნიშანი მოძველებულია.მადლობა საითის გამოიყენებასსაიტის %(site_name)s გუნდიპაროლის ორი ველი ერთმანეთს არ ემთხვევა.ორი {0} ერთმანეთს არ ემთხვევა.ანგარიშის შექმნა შეუძლებულია.შესვლა ამ სახელით და პაროლით არ არის შესაძლებელი.ანგარიში გამორთულია.მომხმარებელის მოდელი არ შეიცავს მითითებულ იმეილის ველს. ნახე http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME მეტი დეტალებისთვისმომხმარებელი ამ იმეილით არ არსებობს.თქვენ იღებთ ამ იმეილს, რადგან საჭიროა დაამთავროთ აკტივაციი პროცესი საიტზე %(site_name)s.ამ ემაილს იღებთ, რანდან თქვნენ მოთხოვეთ პაროლის აღდგენა თქვენი ანგარიშისთვის %(site_name)s საიტზე.თქვენი ანგარიში შეიქმნილია და მზად არის გამოყენებისთვის!თქვენი მომხმარებლის სახელი, იმ შემთხვევისათვის თუ დაგავიწყდათ:././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4013648 djoser-2.1.0/djoser/locale/ka/LC_MESSAGES/django.po0000644000000000000000000001362200000000000016402 0ustar00# Copyright (C) Sunscrapers # This file is distributed under the same license as the djoser package. # msgid "" msgstr "" "Project-Id-Version: 1.4.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-01-25 09:44+0100\n" "PO-Revision-Date: 2019-01-29 14:25+0100\n" "Last-Translator: Szymon Pyżalski \n" "Language-Team: http://sunscrapers.com\n" "Language: ka_GE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: constants.py:4 msgid "Unable to login with provided credentials." msgstr "შესვლა ამ სახელით და პაროლით არ არის შესაძლებელი." #: constants.py:5 msgid "User account is disabled." msgstr "ანგარიში გამორთულია." #: constants.py:6 msgid "Invalid token for given user." msgstr "ნიშანი ტოკენი ამ მომხმარებელისთვის" #: constants.py:7 msgid "Invalid user id or user doesn't exist." msgstr "სახელი არასწორია ან მომხმარებელი არ არსებობს." #: constants.py:8 msgid "Stale token for given user." msgstr "ნიშანი მოძველებულია." #: constants.py:9 msgid "The two password fields didn't match." msgstr "პაროლის ორი ველი ერთმანეთს არ ემთხვევა." #: constants.py:10 #, python-brace-format msgid "The two {0} fields didn't match." msgstr "ორი {0} ერთმანეთს არ ემთხვევა." #: constants.py:11 msgid "Invalid password." msgstr "არასწორი პაროლი." #: constants.py:12 msgid "User with given email does not exist." msgstr "მომხმარებელი ამ იმეილით არ არსებობს." #: constants.py:13 msgid "Unable to create account." msgstr "ანგარიშის შექმნა შეუძლებულია." #: constants.py:15 msgid "" "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." msgstr "მომხმარებელის მოდელი არ შეიცავს მითითებულ იმეილის ველს. ნახე " "http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME " "მეტი დეტალებისთვის" #: templates/email/activation.html:4 #, python-format msgid "Account activation on %(site_name)s" msgstr "ანგარიშის აკტივაცია საიტზე %(site_name)s" #: templates/email/activation.html:8 templates/email/activation.html:19 #, python-format msgid "" "You're receiving this email because you need to finish activation process on " "%(site_name)s." msgstr "თქვენ იღებთ ამ იმეილს, რადგან საჭიროა დაამთავროთ აკტივაციი პროცესი საიტზე %(site_name)s." #: templates/email/activation.html:10 templates/email/activation.html:22 msgid "Please go to the following page to activate account:" msgstr "მიჰყევით ამ ლინკს რათა გაააკტიუროთ ანგარიში:" #: templates/email/activation.html:13 templates/email/activation.html:25 #: templates/email/confirmation.html:10 templates/email/confirmation.html:18 #: templates/email/password_reset.html:14 #: templates/email/password_reset.html:26 msgid "Thanks for using our site!" msgstr "მადლობა საითის გამოიყენებას" #: templates/email/activation.html:15 templates/email/activation.html:27 #: templates/email/confirmation.html:12 templates/email/confirmation.html:20 #: templates/email/password_reset.html:16 #: templates/email/password_reset.html:28 #, python-format msgid "The %(site_name)s team" msgstr "საიტის %(site_name)s გუნდი" #: templates/email/confirmation.html:4 #, python-format msgid "" "%(site_name)s - Your account has been successfully created and activated!" msgstr "%(site_name)s - თქვენი ანგარიში წარმატებით შეიქმნილია და გააკტიურებულია." #: templates/email/confirmation.html:8 templates/email/confirmation.html:16 msgid "Your account has been created and is ready to use!" msgstr "თქვენი ანგარიში შეიქმნილია და მზად არის გამოყენებისთვის!" #: templates/email/password_reset.html:4 #, python-format msgid "Password reset on %(site_name)s" msgstr "პაროლის აღდგენა საიტზე %(site_name)s." #: templates/email/password_reset.html:8 templates/email/password_reset.html:20 #, python-format msgid "" "You're receiving this email because you requested a password reset for your " "user account at %(site_name)s." msgstr "ამ ემაილს იღებთ, რანდან თქვნენ მოთხოვეთ პაროლის აღდგენა თქვენი ანგარიშისთვის " "%(site_name)s საიტზე." #: templates/email/password_reset.html:10 #: templates/email/password_reset.html:22 msgid "Please go to the following page and choose a new password:" msgstr "მოჰყევით ამ ლინკს და მიუთითეთ ახალი პაროლი:" #: templates/email/password_reset.html:12 #: templates/email/password_reset.html:24 msgid "Your username, in case you've forgotten:" msgstr "თქვენი მომხმარებლის სახელი, იმ შემთხვევისათვის თუ დაგავიწყდათ:" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603443965.2843702 djoser-2.1.0/djoser/locale/pl/LC_MESSAGES/django.mo0000644000000000000000000000613000000000000016413 0ustar00I# &+R:r4%0 Vw*%q[j2^((;(H%X:~%4< *Q +|    3 J ] - f6 h 7 > %(site_name)s - Your account has been successfully created and activated!Account activation on %(site_name)sInvalid password.Invalid token for given user.Invalid user id or user doesn't exist.Password reset on %(site_name)sPlease go to the following page and choose a new password:Please go to the following page to activate account:Stale token for given user.Thanks for using our site!The %(site_name)s teamThe two password fields didn't match.The two {0} fields didn't match.Unable to create account.Unable to login with provided credentials.User account is disabled.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.User with given email does not exist.You're receiving this email because you need to finish activation process on %(site_name)s.You're receiving this email because you requested a password reset for your user account at %(site_name)s.Your account has been created and is ready to use!Your username, in case you've forgotten:Project-Id-Version: 1.4.0 Report-Msgid-Bugs-To: POT-Creation-Date: 2019-01-28 15:21+0100 PO-Revision-Date: 2019-01-29 14:25+0100 Last-Translator: Szymon Pyżalski Language: pl_PL Language-Team: http://sunscrapers.com Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 2.8.0 %(site_name)s - Twoje konto zostało stworzone i aktywowaneAktywacja konta na stronie %(site_name)sBłedne hasło.Błędny token dla tego użytkownika.Błędna nazwa użytkownika, lub użytkownik nie istnieje.Reset hasła na stronie %(site_name)sPrzejdź do poniższej strony i wybierz nowe hasło:Proszę przejdź na poniższą stronę, by aktywować konto:Przestarzały token dla tego użytkownika.Dziękujemy za korzystanie z naszej strony!Zespół strony %(site_name)sPola hasła nie pasują.Pola {0} nie pasują.Nie udało się stworzyć konta.Nie udało się zalogować przy pomocy tych danych.Konto wyłączone.Model użytkownika nie zawiera wskazanego pola email. Zobacz http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME by zobaczyć więcej szczegółówUżytkownik z tym adresem email nie istnieje.Otrzymałeś tego emaila, ponieważ potrzeujesz dokończyć proces aktywacji na stronie %(site_name)s.Otrzymałeś tego emaila, ponieważ prosiłeś o reset hasła do Twojego konta na stronie %(site_name)s.Twoje konto zostało utworzone i jest gotowe do użyciaTwoja nazwa użytkownika:././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4016595 djoser-2.1.0/djoser/locale/pl/LC_MESSAGES/django.po0000644000000000000000000001160200000000000016416 0ustar00# Copyright (C) Sunscrapers # This file is distributed under the same license as the djoser package. # msgid "" msgstr "" "Project-Id-Version: 1.4.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-01-28 15:21+0100\n" "PO-Revision-Date: 2019-01-29 14:25+0100\n" "Last-Translator: Szymon Pyżalski \n" "Language-Team: http://sunscrapers.com\n" "Language: pl_PL\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n" "%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n" "%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" #: djoser/constants.py:4 msgid "Unable to login with provided credentials." msgstr "Nie udało się zalogować przy pomocy tych danych." #: djoser/constants.py:5 msgid "User account is disabled." msgstr "Konto wyłączone." #: djoser/constants.py:6 msgid "Invalid token for given user." msgstr "Błędny token dla tego użytkownika." #: djoser/constants.py:7 msgid "Invalid user id or user doesn't exist." msgstr "Błędna nazwa użytkownika, lub użytkownik nie istnieje." #: djoser/constants.py:8 msgid "Stale token for given user." msgstr "Przestarzały token dla tego użytkownika." #: djoser/constants.py:9 msgid "The two password fields didn't match." msgstr "Pola hasła nie pasują." #: djoser/constants.py:10 #, python-brace-format msgid "The two {0} fields didn't match." msgstr "Pola {0} nie pasują." #: djoser/constants.py:11 msgid "Invalid password." msgstr "Błedne hasło." #: djoser/constants.py:12 msgid "User with given email does not exist." msgstr "Użytkownik z tym adresem email nie istnieje." #: djoser/constants.py:13 msgid "Unable to create account." msgstr "Nie udało się stworzyć konta." #: djoser/constants.py:15 msgid "" "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." msgstr "Model użytkownika nie zawiera wskazanego pola email. Zobacz " "http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME " "by zobaczyć więcej szczegółów" #: djoser/templates/email/activation.html:4 #, python-format msgid "Account activation on %(site_name)s" msgstr "Aktywacja konta na stronie %(site_name)s" #: templates/email/activation.html:8 templates/email/activation.html:19 #, python-format msgid "" "You're receiving this email because you need to finish activation process on " "%(site_name)s." msgstr "Otrzymałeś tego emaila, ponieważ potrzeujesz dokończyć proces aktywacji na " "stronie %(site_name)s." #: djoser/templates/email/activation.html:10 #: djoser/templates/email/activation.html:22 msgid "Please go to the following page to activate account:" msgstr "Proszę przejdź na poniższą stronę, by aktywować konto:" #: djoser/templates/email/activation.html:13 #: djoser/templates/email/activation.html:25 #: djoser/templates/email/confirmation.html:10 #: djoser/templates/email/confirmation.html:18 #: djoser/templates/email/password_reset.html:14 #: djoser/templates/email/password_reset.html:26 msgid "Thanks for using our site!" msgstr "Dziękujemy za korzystanie z naszej strony!" #: djoser/templates/email/activation.html:15 #: djoser/templates/email/activation.html:27 #: djoser/templates/email/confirmation.html:12 #: djoser/templates/email/confirmation.html:20 #: djoser/templates/email/password_reset.html:16 #: djoser/templates/email/password_reset.html:28 #, python-format msgid "The %(site_name)s team" msgstr "Zespół strony %(site_name)s" #: djoser/templates/email/confirmation.html:4 #, python-format msgid "" "%(site_name)s - Your account has been successfully created and activated!" msgstr "%(site_name)s - Twoje konto zostało stworzone i aktywowane" #: djoser/templates/email/confirmation.html:8 #: djoser/templates/email/confirmation.html:16 msgid "Your account has been created and is ready to use!" msgstr "Twoje konto zostało utworzone i jest gotowe do użycia" #: djoser/templates/email/password_reset.html:4 #, python-format msgid "Password reset on %(site_name)s" msgstr "Reset hasła na stronie %(site_name)s" #: djoser/templates/email/password_reset.html:8 #: djoser/templates/email/password_reset.html:20 #, python-format msgid "" "You're receiving this email because you requested a password reset for your " "user account at %(site_name)s." msgstr "Otrzymałeś tego emaila, ponieważ prosiłeś o reset hasła do Twojego " "konta na stronie %(site_name)s." #: djoser/templates/email/password_reset.html:10 #: djoser/templates/email/password_reset.html:22 msgid "Please go to the following page and choose a new password:" msgstr "Przejdź do poniższej strony i wybierz nowe hasło:" #: djoser/templates/email/password_reset.html:12 #: djoser/templates/email/password_reset.html:24 msgid "Your username, in case you've forgotten:" msgstr "Twoja nazwa użytkownika:" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603443965.2874196 djoser-2.1.0/djoser/locale/pt_BR/LC_MESSAGES/django.mo0000644000000000000000000000575200000000000017017 0ustar00I# &+R:r4%0 Vw*%q[j2^(;S$*(#A=;) & &= !d 6 % . [ q 9 # %(site_name)s - Your account has been successfully created and activated!Account activation on %(site_name)sInvalid password.Invalid token for given user.Invalid user id or user doesn't exist.Password reset on %(site_name)sPlease go to the following page and choose a new password:Please go to the following page to activate account:Stale token for given user.Thanks for using our site!The %(site_name)s teamThe two password fields didn't match.The two {0} fields didn't match.Unable to create account.Unable to login with provided credentials.User account is disabled.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.User with given email does not exist.You're receiving this email because you need to finish activation process on %(site_name)s.You're receiving this email because you requested a password reset for your user account at %(site_name)s.Your account has been created and is ready to use!Your username, in case you've forgotten:Project-Id-Version: djoser commit 298825d on master Report-Msgid-Bugs-To: POT-Creation-Date: 2020-03-18 21:45-0300 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: Matheus Gomes Language: pt_BR Language-Team: Brasileiro Plural-Forms: nplurals=2; plural=(n > 1) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 2.8.0 %(site_name)s - Sua conta foi criada e ativada com sucesso!Ativação de conta em %(site_name)sSenha inválida.Token inválido para o usuário fornecido.ID de usuário inválido ou inexistente.Redefina sua senha em %(site_name)sPor favor, visite a seguinte página para definir uma senha nova:Por favor, visite a seguinte página para ativar sua conta:Token expirado para o usuário fornecido.Obrigado por usar nosso site!Time %(site_name)sOs campos de senha não estão iguais.Os dois campos {0} não estão iguais.Não foi possível criar a conta.Não foi possível fazer login com os dados inseridos.A conta do usuário está desativada.O usuário fornecido não possui campo de email definido. Por favor, confira http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME para mais detalhes.Não existe um usuário com o email fornecido.Você está recebendo este email porque você precisa terminar o processo em %(site_name)s.Você está recebendo este email porque você solicitou a redefinição de senha para sua conta em %(site_name)s.Sua conta foi criada com sucesso e está pronta para uso!Caso tenha esquecido, seu usuário:././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603449460.3559828 djoser-2.1.0/djoser/locale/pt_BR/LC_MESSAGES/django.po0000644000000000000000000001135500000000000017016 0ustar00# Copyright (C) Sunscrapers # This file is distributed under the same license as the djoser package. # msgid "" msgstr "" "Project-Id-Version: djoser commit 298825d on master\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-03-18 21:45-0300\n" "Last-Translator: Matheus Gomes \n" "Language-Team: Brasileiro\n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: djoser/constants.py:4 msgid "Unable to login with provided credentials." msgstr "Não foi possível fazer login com os dados inseridos." #: djoser/constants.py:5 msgid "User account is disabled." msgstr "A conta do usuário está desativada." #: djoser/constants.py:6 msgid "Invalid token for given user." msgstr "Token inválido para o usuário fornecido." #: djoser/constants.py:7 msgid "Invalid user id or user doesn't exist." msgstr "ID de usuário inválido ou inexistente." #: djoser/constants.py:8 msgid "Stale token for given user." msgstr "Token expirado para o usuário fornecido." #: djoser/constants.py:9 msgid "The two password fields didn't match." msgstr "Os campos de senha não estão iguais." #: djoser/constants.py:10 #, python-brace-format msgid "The two {0} fields didn't match." msgstr "Os dois campos {0} não estão iguais." #: djoser/constants.py:11 msgid "Invalid password." msgstr "Senha inválida." #: djoser/constants.py:12 msgid "User with given email does not exist." msgstr "Não existe um usuário com o email fornecido." #: djoser/constants.py:13 msgid "Unable to create account." msgstr "Não foi possível criar a conta." #: djoser/constants.py:15 msgid "" "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." msgstr "" "O usuário fornecido não possui campo de email definido. Por favor, confira " "http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME " "para mais detalhes." #: djoser/templates/email/activation.html:4 #, python-format msgid "Account activation on %(site_name)s" msgstr "Ativação de conta em %(site_name)s" #: templates/email/activation.html:8 templates/email/activation.html:19 #, python-format msgid "" "You're receiving this email because you need to finish activation process on " "%(site_name)s." msgstr "" "Você está recebendo este email porque você precisa terminar o processo em " "%(site_name)s." #: djoser/templates/email/activation.html:10 #: djoser/templates/email/activation.html:22 msgid "Please go to the following page to activate account:" msgstr "Por favor, visite a seguinte página para ativar sua conta:" #: djoser/templates/email/activation.html:13 #: djoser/templates/email/activation.html:25 #: djoser/templates/email/confirmation.html:10 #: djoser/templates/email/confirmation.html:18 #: djoser/templates/email/password_reset.html:14 #: djoser/templates/email/password_reset.html:26 msgid "Thanks for using our site!" msgstr "Obrigado por usar nosso site!" #: djoser/templates/email/activation.html:15 #: djoser/templates/email/activation.html:27 #: djoser/templates/email/confirmation.html:12 #: djoser/templates/email/confirmation.html:20 #: djoser/templates/email/password_reset.html:16 #: djoser/templates/email/password_reset.html:28 #, python-format msgid "The %(site_name)s team" msgstr "Time %(site_name)s" #: djoser/templates/email/confirmation.html:4 #, python-format msgid "" "%(site_name)s - Your account has been successfully created and activated!" msgstr "%(site_name)s - Sua conta foi criada e ativada com sucesso!" #: djoser/templates/email/confirmation.html:8 #: djoser/templates/email/confirmation.html:16 msgid "Your account has been created and is ready to use!" msgstr "Sua conta foi criada com sucesso e está pronta para uso!" #: djoser/templates/email/password_reset.html:4 #, python-format msgid "Password reset on %(site_name)s" msgstr "Redefina sua senha em %(site_name)s" #: djoser/templates/email/password_reset.html:8 #: djoser/templates/email/password_reset.html:20 #, python-format msgid "" "You're receiving this email because you requested a password reset for your " "user account at %(site_name)s." msgstr "" "Você está recebendo este email porque você solicitou a redefinição de senha " "para sua conta em %(site_name)s." #: djoser/templates/email/password_reset.html:10 #: djoser/templates/email/password_reset.html:22 msgid "Please go to the following page and choose a new password:" msgstr "Por favor, visite a seguinte página para definir uma senha nova:" #: djoser/templates/email/password_reset.html:12 #: djoser/templates/email/password_reset.html:24 msgid "Your username, in case you've forgotten:" msgstr "Caso tenha esquecido, seu usuário:" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603443965.2975895 djoser-2.1.0/djoser/locale/ru_RU/LC_MESSAGES/django.mo0000644000000000000000000001016600000000000017040 0ustar00I# &+R:r4%0 Vw*%q[j2^(x6&4K[*' ~R Oe G  , =G @ d I+ Du t /kE0%(site_name)s - Your account has been successfully created and activated!Account activation on %(site_name)sInvalid password.Invalid token for given user.Invalid user id or user doesn't exist.Password reset on %(site_name)sPlease go to the following page and choose a new password:Please go to the following page to activate account:Stale token for given user.Thanks for using our site!The %(site_name)s teamThe two password fields didn't match.The two {0} fields didn't match.Unable to create account.Unable to login with provided credentials.User account is disabled.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.User with given email does not exist.You're receiving this email because you need to finish activation process on %(site_name)s.You're receiving this email because you requested a password reset for your user account at %(site_name)s.Your account has been created and is ready to use!Your username, in case you've forgotten:Project-Id-Version: 1.4.0 Report-Msgid-Bugs-To: POT-Creation-Date: 2019-01-28 15:21+0100 PO-Revision-Date: 2019-05-14 12:05+0300 Last-Translator: Sergey Ozeranskiy Language: ru_RU Language-Team: Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Generated-By: Babel 2.8.0 %(site_name)s - Ваша учетная запись была успешно создана и активирована!Активация аккаунта на %(site_name)sНеправильный пароль.Неверный токен для данного пользователя.Неверный идентификатор пользователя или пользователь не существует.Сброс пароля на %(site_name)sПожалуйста, перейдите на следующую страницу и создайте новый пароль:Пожалуйста, перейдите на следующую страницу, чтобы активировать учетную запись:Устаревший токен для данного пользователя.Спасибо за использование нашего сайта!Команда %(site_name)sДва пароля не совпадают.Два значения поля {0} не совпадают.Невозможно создать учетную запись.Невозможно войти с предоставленными учетными данными.Учетная запись пользователя не активна.Модель пользователя не содержит указанное поле для электронной почты. Пожалуйста, посмотрите http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME для получения дополнительной информации.Пользователь с данным адресом электронной почты не существует.Вы получили это письмо, потому что вам нужно завершить процесс активации учетной записи на %(site_name)s.Вы получили это письмо, потому что вы или кто-то другой запросили сброс пароля для учетной записи пользователя на %(site_name)s.Ваша учетная запись была создана и готова к использованию!Ваше имя пользователя, если вы забыли:././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4023178 djoser-2.1.0/djoser/locale/ru_RU/LC_MESSAGES/django.po0000644000000000000000000001400700000000000017041 0ustar00# Copyright (C) Sunscrapers # This file is distributed under the same license as the djoser package. # msgid "" msgstr "" "Project-Id-Version: 1.4.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2019-01-28 15:21+0100\n" "PO-Revision-Date: 2019-05-14 12:05+0300\n" "Last-Translator: Sergey Ozeranskiy \n" "Language-Team: \n" "Language: ru_RU\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n" "%100<12 || n%100>14) ? 1 : 2);\n" "X-Generator: Poedit 2.2.1\n" "X-Poedit-Basepath: ../../../..\n" "X-Poedit-SearchPath-0: .\n" #: djoser/constants.py:4 msgid "Unable to login with provided credentials." msgstr "Невозможно войти с предоставленными учетными данными." #: djoser/constants.py:5 msgid "User account is disabled." msgstr "Учетная запись пользователя не активна." #: djoser/constants.py:6 msgid "Invalid token for given user." msgstr "Неверный токен для данного пользователя." #: djoser/constants.py:7 msgid "Invalid user id or user doesn't exist." msgstr "Неверный идентификатор пользователя или пользователь не существует." #: djoser/constants.py:8 msgid "Stale token for given user." msgstr "Устаревший токен для данного пользователя." #: djoser/constants.py:9 msgid "The two password fields didn't match." msgstr "Два пароля не совпадают." #: djoser/constants.py:10 #, python-brace-format msgid "The two {0} fields didn't match." msgstr "Два значения поля {0} не совпадают." #: djoser/constants.py:11 msgid "Invalid password." msgstr "Неправильный пароль." #: djoser/constants.py:12 msgid "User with given email does not exist." msgstr "Пользователь с данным адресом электронной почты не существует." #: djoser/constants.py:13 msgid "Unable to create account." msgstr "Невозможно создать учетную запись." #: djoser/constants.py:15 msgid "" "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." msgstr "" "Модель пользователя не содержит указанное поле для электронной почты. Пожалуйста, " "посмотрите http://djoser.readthedocs.io/en/latest/settings." "html#USER_EMAIL_FIELD_NAME для получения дополнительной информации." #: djoser/templates/email/activation.html:4 #, python-format msgid "Account activation on %(site_name)s" msgstr "Активация аккаунта на %(site_name)s" #: djoser/templates/email/activation.html:8 djoser/templates/email/activation.html:19 #, python-format msgid "" "You're receiving this email because you need to finish activation process on " "%(site_name)s." msgstr "" "Вы получили это письмо, потому что вам нужно завершить процесс активации учетной " "записи на %(site_name)s." #: djoser/templates/email/activation.html:10 djoser/templates/email/activation.html:22 msgid "Please go to the following page to activate account:" msgstr "" "Пожалуйста, перейдите на следующую страницу, чтобы активировать учетную запись:" #: djoser/templates/email/activation.html:13 djoser/templates/email/activation.html:25 #: djoser/templates/email/confirmation.html:10 #: djoser/templates/email/confirmation.html:18 #: djoser/templates/email/password_reset.html:14 #: djoser/templates/email/password_reset.html:26 msgid "Thanks for using our site!" msgstr "Спасибо за использование нашего сайта!" #: djoser/templates/email/activation.html:15 djoser/templates/email/activation.html:27 #: djoser/templates/email/confirmation.html:12 #: djoser/templates/email/confirmation.html:20 #: djoser/templates/email/password_reset.html:16 #: djoser/templates/email/password_reset.html:28 #, python-format msgid "The %(site_name)s team" msgstr "Команда %(site_name)s" #: djoser/templates/email/confirmation.html:4 #, python-format msgid "%(site_name)s - Your account has been successfully created and activated!" msgstr "%(site_name)s - Ваша учетная запись была успешно создана и активирована!" #: djoser/templates/email/confirmation.html:8 #: djoser/templates/email/confirmation.html:16 msgid "Your account has been created and is ready to use!" msgstr "Ваша учетная запись была создана и готова к использованию!" #: djoser/templates/email/password_reset.html:4 #, python-format msgid "Password reset on %(site_name)s" msgstr "Сброс пароля на %(site_name)s" #: djoser/templates/email/password_reset.html:8 #: djoser/templates/email/password_reset.html:20 #, python-format msgid "" "You're receiving this email because you requested a password reset for your user " "account at %(site_name)s." msgstr "" "Вы получили это письмо, потому что вы или кто-то другой запросили сброс пароля для " "учетной записи пользователя на %(site_name)s." #: djoser/templates/email/password_reset.html:10 #: djoser/templates/email/password_reset.html:22 msgid "Please go to the following page and choose a new password:" msgstr "Пожалуйста, перейдите на следующую страницу и создайте новый пароль:" #: djoser/templates/email/password_reset.html:12 #: djoser/templates/email/password_reset.html:24 msgid "Your username, in case you've forgotten:" msgstr "Ваше имя пользователя, если вы забыли:" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1603274433.402485 djoser-2.1.0/djoser/permissions.py0000644000000000000000000000107600000000000014106 0ustar00from rest_framework import permissions from rest_framework.permissions import SAFE_METHODS class CurrentUserOrAdmin(permissions.IsAuthenticated): def has_object_permission(self, request, view, obj): user = request.user return user.is_staff or obj.pk == user.pk class CurrentUserOrAdminOrReadOnly(permissions.IsAuthenticated): def has_object_permission(self, request, view, obj): user = request.user if type(obj) == type(user) and obj == user: return True return request.method in SAFE_METHODS or user.is_staff ././@PaxHeader0000000000000000000000000000003100000000000010207 xustar0025 mtime=1603274433.4027 djoser-2.1.0/djoser/serializers.py0000644000000000000000000002541200000000000014067 0ustar00from django.contrib.auth import authenticate, get_user_model from django.contrib.auth.password_validation import validate_password from django.core import exceptions as django_exceptions from django.db import IntegrityError, transaction from rest_framework import exceptions, serializers from rest_framework.exceptions import ValidationError from djoser import utils from djoser.compat import get_user_email, get_user_email_field_name from djoser.conf import settings User = get_user_model() class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = tuple(User.REQUIRED_FIELDS) + ( settings.USER_ID_FIELD, settings.LOGIN_FIELD, ) read_only_fields = (settings.LOGIN_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().update(instance, validated_data) class UserCreateSerializer(serializers.ModelSerializer): password = serializers.CharField(style={"input_type": "password"}, write_only=True) default_error_messages = { "cannot_create_user": settings.CONSTANTS.messages.CANNOT_CREATE_USER_ERROR } class Meta: model = User fields = tuple(User.REQUIRED_FIELDS) + ( settings.LOGIN_FIELD, settings.USER_ID_FIELD, "password", ) def validate(self, attrs): user = User(**attrs) password = attrs.get("password") try: validate_password(password, user) except django_exceptions.ValidationError as e: serializer_error = serializers.as_serializer_error(e) raise serializers.ValidationError( {"password": serializer_error["non_field_errors"]} ) return attrs def create(self, validated_data): try: user = self.perform_create(validated_data) except IntegrityError: self.fail("cannot_create_user") return user def perform_create(self, validated_data): with transaction.atomic(): user = User.objects.create_user(**validated_data) if settings.SEND_ACTIVATION_EMAIL: user.is_active = False user.save(update_fields=["is_active"]) return user class UserCreatePasswordRetypeSerializer(UserCreateSerializer): default_error_messages = { "password_mismatch": settings.CONSTANTS.messages.PASSWORD_MISMATCH_ERROR } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["re_password"] = serializers.CharField( style={"input_type": "password"} ) def validate(self, attrs): self.fields.pop("re_password", None) re_password = attrs.pop("re_password") attrs = super().validate(attrs) if attrs["password"] == re_password: return attrs else: self.fail("password_mismatch") class TokenCreateSerializer(serializers.Serializer): password = serializers.CharField(required=False, style={"input_type": "password"}) default_error_messages = { "invalid_credentials": settings.CONSTANTS.messages.INVALID_CREDENTIALS_ERROR, "inactive_account": settings.CONSTANTS.messages.INACTIVE_ACCOUNT_ERROR, } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.user = None self.fields[settings.LOGIN_FIELD] = serializers.CharField(required=False) def validate(self, attrs): password = attrs.get("password") params = {settings.LOGIN_FIELD: attrs.get(settings.LOGIN_FIELD)} self.user = authenticate( request=self.context.get("request"), **params, password=password ) if not self.user: self.user = User.objects.filter(**params).first() if self.user and not self.user.check_password(password): self.fail("invalid_credentials") if self.user and self.user.is_active: return attrs self.fail("invalid_credentials") class UserFunctionsMixin: def get_user(self, is_active=True): try: user = User._default_manager.get( is_active=is_active, **{self.email_field: self.data.get(self.email_field, "")}, ) if user.has_usable_password(): return user except User.DoesNotExist: pass if ( settings.PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND or settings.USERNAME_RESET_SHOW_EMAIL_NOT_FOUND ): self.fail("email_not_found") class SendEmailResetSerializer(serializers.Serializer, UserFunctionsMixin): default_error_messages = { "email_not_found": settings.CONSTANTS.messages.EMAIL_NOT_FOUND } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.email_field = get_user_email_field_name(User) self.fields[self.email_field] = serializers.EmailField() class UidAndTokenSerializer(serializers.Serializer): uid = serializers.CharField() token = serializers.CharField() default_error_messages = { "invalid_token": settings.CONSTANTS.messages.INVALID_TOKEN_ERROR, "invalid_uid": settings.CONSTANTS.messages.INVALID_UID_ERROR, } def validate(self, attrs): validated_data = super().validate(attrs) # uid validation have to be here, because validate_ # doesn't work with modelserializer try: uid = utils.decode_uid(self.initial_data.get("uid", "")) self.user = User.objects.get(pk=uid) except (User.DoesNotExist, ValueError, TypeError, OverflowError): key_error = "invalid_uid" raise ValidationError( {"uid": [self.error_messages[key_error]]}, code=key_error ) is_token_valid = self.context["view"].token_generator.check_token( self.user, self.initial_data.get("token", "") ) if is_token_valid: return validated_data else: key_error = "invalid_token" raise ValidationError( {"token": [self.error_messages[key_error]]}, code=key_error ) class ActivationSerializer(UidAndTokenSerializer): default_error_messages = { "stale_token": settings.CONSTANTS.messages.STALE_TOKEN_ERROR } def validate(self, attrs): attrs = super().validate(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"}) def validate(self, attrs): user = self.context["request"].user or self.user # why assert? There are ValidationError / fail everywhere assert user is not None try: validate_password(attrs["new_password"], user) except django_exceptions.ValidationError as e: raise serializers.ValidationError({"new_password": list(e.messages)}) return super().validate(attrs) class PasswordRetypeSerializer(PasswordSerializer): re_new_password = serializers.CharField(style={"input_type": "password"}) default_error_messages = { "password_mismatch": settings.CONSTANTS.messages.PASSWORD_MISMATCH_ERROR } def validate(self, attrs): attrs = super().validate(attrs) if attrs["new_password"] == attrs["re_new_password"]: return attrs else: self.fail("password_mismatch") class CurrentPasswordSerializer(serializers.Serializer): current_password = serializers.CharField(style={"input_type": "password"}) default_error_messages = { "invalid_password": settings.CONSTANTS.messages.INVALID_PASSWORD_ERROR } def validate_current_password(self, value): is_password_valid = self.context["request"].user.check_password(value) if is_password_valid: return value else: self.fail("invalid_password") class UsernameSerializer(serializers.ModelSerializer): class Meta: model = User fields = (settings.LOGIN_FIELD,) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.username_field = settings.LOGIN_FIELD self._default_username_field = User.USERNAME_FIELD self.fields["new_{}".format(self.username_field)] = self.fields.pop( self.username_field ) def save(self, **kwargs): if self.username_field != self._default_username_field: kwargs[User.USERNAME_FIELD] = self.validated_data.get( "new_{}".format(self.username_field) ) return super().save(**kwargs) class UsernameRetypeSerializer(UsernameSerializer): default_error_messages = { "username_mismatch": settings.CONSTANTS.messages.USERNAME_MISMATCH_ERROR.format( settings.LOGIN_FIELD ) } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["re_new_" + settings.LOGIN_FIELD] = serializers.CharField() def validate(self, attrs): attrs = super().validate(attrs) new_username = attrs[settings.LOGIN_FIELD] if new_username != attrs["re_new_{}".format(settings.LOGIN_FIELD)]: self.fail("username_mismatch") else: return attrs class TokenSerializer(serializers.ModelSerializer): auth_token = serializers.CharField(source="key") class Meta: model = settings.TOKEN_MODEL fields = ("auth_token",) class SetPasswordSerializer(PasswordSerializer, CurrentPasswordSerializer): pass class SetPasswordRetypeSerializer(PasswordRetypeSerializer, CurrentPasswordSerializer): pass class PasswordResetConfirmSerializer(UidAndTokenSerializer, PasswordSerializer): pass class PasswordResetConfirmRetypeSerializer( UidAndTokenSerializer, PasswordRetypeSerializer ): pass class UsernameResetConfirmSerializer(UidAndTokenSerializer, UsernameSerializer): pass class UsernameResetConfirmRetypeSerializer( UidAndTokenSerializer, UsernameRetypeSerializer ): pass class UserDeleteSerializer(CurrentPasswordSerializer): pass class SetUsernameSerializer(UsernameSerializer, CurrentPasswordSerializer): class Meta: model = User fields = (settings.LOGIN_FIELD, "current_password") class SetUsernameRetypeSerializer(SetUsernameSerializer, UsernameRetypeSerializer): pass ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1603274433.402852 djoser-2.1.0/djoser/signals.py0000644000000000000000000000031000000000000013161 0ustar00from django.dispatch import Signal # New user has registered. Args: user, request. user_registered = Signal() # User has activated his or her account. Args: user, request. user_activated = Signal() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4030023 djoser-2.1.0/djoser/social/__init__.py0000644000000000000000000000000000000000000014526 0ustar00././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4031503 djoser-2.1.0/djoser/social/backends/__init__.py0000644000000000000000000000000000000000000016300 0ustar00././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4032903 djoser-2.1.0/djoser/social/backends/facebook.py0000644000000000000000000000020400000000000016320 0ustar00from social_core.backends.facebook import FacebookOAuth2 class FacebookOAuth2Override(FacebookOAuth2): REDIRECT_STATE = False ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4034667 djoser-2.1.0/djoser/social/serializers.py0000644000000000000000000000373600000000000015346 0ustar00from rest_framework import serializers from social_core import exceptions from social_django.utils import load_backend, load_strategy from djoser.conf import settings class ProviderAuthSerializer(serializers.Serializer): # GET auth token access = serializers.CharField(read_only=True) refresh = serializers.CharField(read_only=True) user = serializers.CharField(read_only=True) def create(self, validated_data): user = validated_data["user"] return settings.SOCIAL_AUTH_TOKEN_STRATEGY.obtain(user) def validate(self, attrs): request = self.context["request"] if "state" in request.GET: self._validate_state(request.GET["state"]) strategy = load_strategy(request) redirect_uri = strategy.session_get("redirect_uri") backend_name = self.context["view"].kwargs["provider"] backend = load_backend(strategy, backend_name, redirect_uri=redirect_uri) try: user = backend.auth_complete() except exceptions.AuthException as e: raise serializers.ValidationError(str(e)) return {"user": user} def _validate_state(self, value): request = self.context["request"] strategy = load_strategy(request) redirect_uri = strategy.session_get("redirect_uri") backend_name = self.context["view"].kwargs["provider"] backend = load_backend(strategy, backend_name, redirect_uri=redirect_uri) try: backend.validate_state() except exceptions.AuthMissingParameter: raise serializers.ValidationError( "State could not be found in request data." ) except exceptions.AuthStateMissing: raise serializers.ValidationError( "State could not be found in server-side session data." ) except exceptions.AuthStateForbidden: raise serializers.ValidationError("Invalid state has been provided.") return value ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4036167 djoser-2.1.0/djoser/social/token/__init__.py0000644000000000000000000000000000000000000015646 0ustar00././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4037688 djoser-2.1.0/djoser/social/token/jwt.py0000644000000000000000000000055200000000000014727 0ustar00class TokenStrategy: @classmethod def obtain(cls, user): from rest_framework_simplejwt.tokens import RefreshToken from six import text_type refresh = RefreshToken.for_user(user) return { "access": text_type(refresh.access_token), "refresh": text_type(refresh), "user": user, } ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603449460.3564432 djoser-2.1.0/djoser/social/urls.py0000644000000000000000000000032200000000000013763 0ustar00from django.urls import re_path from djoser.social import views urlpatterns = [ re_path( r"^o/(?P\S+)/$", views.ProviderAuthView.as_view(), name="provider-auth", ) ] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4040592 djoser-2.1.0/djoser/social/views.py0000644000000000000000000000173700000000000014146 0ustar00from rest_framework import generics, permissions, status from rest_framework.response import Response from social_django.utils import load_backend, load_strategy from djoser.conf import settings from djoser.social.serializers import ProviderAuthSerializer class ProviderAuthView(generics.CreateAPIView): permission_classes = [permissions.AllowAny] serializer_class = ProviderAuthSerializer def get(self, request, *args, **kwargs): redirect_uri = request.GET.get("redirect_uri") if redirect_uri not in settings.SOCIAL_AUTH_ALLOWED_REDIRECT_URIS: return Response(status=status.HTTP_400_BAD_REQUEST) strategy = load_strategy(request) strategy.session_set("redirect_uri", redirect_uri) backend_name = self.kwargs["provider"] backend = load_backend(strategy, backend_name, redirect_uri=redirect_uri) authorization_url = backend.auth_url() return Response(data={"authorization_url": authorization_url}) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4044406 djoser-2.1.0/djoser/templates/email/activation.html0000644000000000000000000000176600000000000017303 0ustar00{% load i18n %} {% block subject %} {% blocktrans %}Account activation on {{ site_name }}{% endblocktrans %} {% endblock subject %} {% block text_body %} {% blocktrans %}You're receiving this email because you need to finish activation process on {{ site_name }}.{% endblocktrans %} {% trans "Please go to the following page to activate account:" %} {{ protocol }}://{{ domain }}/{{ url|safe }} {% trans "Thanks for using our site!" %} {% blocktrans %}The {{ site_name }} team{% endblocktrans %} {% endblock text_body %} {% block html_body %}

{% blocktrans %}You're receiving this email because you need to finish activation process on {{ site_name }}.{% endblocktrans %}

{% trans "Please go to the following page to activate account:" %}

{{ protocol }}://{{ domain }}/{{ url|safe }}

{% trans "Thanks for using our site!" %}

{% blocktrans %}The {{ site_name }} team{% endblocktrans %}

{% endblock html_body %} ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4046214 djoser-2.1.0/djoser/templates/email/confirmation.html0000644000000000000000000000115000000000000017615 0ustar00{% load i18n %} {% block subject %} {% blocktrans %}{{ site_name }} - Your account has been successfully created and activated!{% endblocktrans %} {% endblock %} {% block text_body %} {% trans "Your account has been created and is ready to use!" %} {% trans "Thanks for using our site!" %} {% blocktrans %}The {{ site_name }} team{% endblocktrans %} {% endblock text_body %} {% block html_body %}

{% trans "Your account has been created and is ready to use!" %}

{% trans "Thanks for using our site!" %}

{% blocktrans %}The {{ site_name }} team{% endblocktrans %}

{% endblock html_body %} ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1603274433.404794 djoser-2.1.0/djoser/templates/email/password_changed_confirmation.html0000644000000000000000000000106500000000000023215 0ustar00{% load i18n %} {% block subject %} {% blocktrans %}{{ site_name }} - Your password has been successfully changed!{% endblocktrans %} {% endblock %} {% block text_body %} {% trans "Your password has been changed!" %} {% trans "Thanks for using our site!" %} {% blocktrans %}The {{ site_name }} team{% endblocktrans %} {% endblock text_body %} {% block html_body %}

{% trans "Your password has been changed!" %}

{% trans "Thanks for using our site!" %}

{% blocktrans %}The {{ site_name }} team{% endblocktrans %}

{% endblock html_body %} ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4049609 djoser-2.1.0/djoser/templates/email/password_reset.html0000644000000000000000000000226100000000000020175 0ustar00{% load i18n %} {% block subject %} {% blocktrans %}Password reset on {{ site_name }}{% endblocktrans %} {% endblock subject %} {% block text_body %} {% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %} {% trans "Please go to the following page and choose a new password:" %} {{ protocol }}://{{ domain }}/{{ url }} {% trans "Your username, in case you've forgotten:" %} {{ user.get_username }} {% trans "Thanks for using our site!" %} {% blocktrans %}The {{ site_name }} team{% endblocktrans %} {% endblock text_body %} {% block html_body %}

{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}

{% trans "Please go to the following page and choose a new password:" %}

{{ protocol }}://{{ domain }}/{{ url }}

{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}

{% trans "Thanks for using our site!" %}

{% blocktrans %}The {{ site_name }} team{% endblocktrans %}

{% endblock html_body %} ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1603274433.405139 djoser-2.1.0/djoser/templates/email/username_changed_confirmation.html0000644000000000000000000000106500000000000023172 0ustar00{% load i18n %} {% block subject %} {% blocktrans %}{{ site_name }} - Your username has been successfully changed!{% endblocktrans %} {% endblock %} {% block text_body %} {% trans "Your username has been changed!" %} {% trans "Thanks for using our site!" %} {% blocktrans %}The {{ site_name }} team{% endblocktrans %} {% endblock text_body %} {% block html_body %}

{% trans "Your username has been changed!" %}

{% trans "Thanks for using our site!" %}

{% blocktrans %}The {{ site_name }} team{% endblocktrans %}

{% endblock html_body %} ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1603274433.405301 djoser-2.1.0/djoser/templates/email/username_reset.html0000644000000000000000000000226100000000000020152 0ustar00{% load i18n %} {% block subject %} {% blocktrans %}Username reset on {{ site_name }}{% endblocktrans %} {% endblock subject %} {% block text_body %} {% blocktrans %}You're receiving this email because you requested a username reset for your user account at {{ site_name }}.{% endblocktrans %} {% trans "Please go to the following page and choose a new username:" %} {{ protocol }}://{{ domain }}/{{ url }} {% trans "Your username, in case you've forgotten:" %} {{ user.get_username }} {% trans "Thanks for using our site!" %} {% blocktrans %}The {{ site_name }} team{% endblocktrans %} {% endblock text_body %} {% block html_body %}

{% blocktrans %}You're receiving this email because you requested a username reset for your user account at {{ site_name }}.{% endblocktrans %}

{% trans "Please go to the following page and choose a new username:" %}

{{ protocol }}://{{ domain }}/{{ url }}

{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}

{% trans "Thanks for using our site!" %}

{% blocktrans %}The {{ site_name }} team{% endblocktrans %}

{% endblock html_body %} ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4055452 djoser-2.1.0/djoser/urls/__init__.py0000644000000000000000000000007100000000000014251 0ustar00from .base import urlpatterns __all__ = ["urlpatterns"] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4057121 djoser-2.1.0/djoser/urls/authtoken.py0000644000000000000000000000036000000000000014515 0ustar00from django.urls import re_path from djoser import views urlpatterns = [ re_path(r"^token/login/?$", views.TokenCreateView.as_view(), name="login"), re_path(r"^token/logout/?$", views.TokenDestroyView.as_view(), name="logout"), ] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4059036 djoser-2.1.0/djoser/urls/base.py0000644000000000000000000000036400000000000013431 0ustar00from django.contrib.auth import get_user_model from rest_framework.routers import DefaultRouter from djoser import views router = DefaultRouter() router.register("users", views.UserViewSet) User = get_user_model() urlpatterns = router.urls ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1603274433.406113 djoser-2.1.0/djoser/urls/jwt.py0000644000000000000000000000053600000000000013324 0ustar00from django.urls import re_path from rest_framework_simplejwt import views urlpatterns = [ re_path(r"^jwt/create/?", views.TokenObtainPairView.as_view(), name="jwt-create"), re_path(r"^jwt/refresh/?", views.TokenRefreshView.as_view(), name="jwt-refresh"), re_path(r"^jwt/verify/?", views.TokenVerifyView.as_view(), name="jwt-verify"), ] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603274433.4063144 djoser-2.1.0/djoser/utils.py0000644000000000000000000000225400000000000012672 0ustar00from django.contrib.auth import login, logout, user_logged_in, user_logged_out from django.utils.encoding import force_bytes, force_str from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode from djoser.conf import settings def encode_uid(pk): return force_str(urlsafe_base64_encode(force_bytes(pk))) def decode_uid(pk): return force_str(urlsafe_base64_decode(pk)) def login_user(request, user): token, _ = settings.TOKEN_MODEL.objects.get_or_create(user=user) if settings.CREATE_SESSION_ON_LOGIN: login(request, user) user_logged_in.send(sender=user.__class__, request=request, user=user) return token def logout_user(request): if settings.TOKEN_MODEL: settings.TOKEN_MODEL.objects.filter(user=request.user).delete() user_logged_out.send( sender=request.user.__class__, request=request, user=request.user ) if settings.CREATE_SESSION_ON_LOGIN: logout(request) class ActionViewMixin(object): def post(self, request, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) return self._action(serializer) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603370635.2424462 djoser-2.1.0/djoser/views.py0000644000000000000000000003065600000000000012676 0ustar00from django.contrib.auth import get_user_model, update_session_auth_hash from django.contrib.auth.tokens import default_token_generator from django.utils.timezone import now from rest_framework import generics, status, views, viewsets from rest_framework.decorators import action from rest_framework.exceptions import NotFound from rest_framework.response import Response from djoser import signals, utils from djoser.compat import get_user_email from djoser.conf import settings User = get_user_model() class TokenCreateView(utils.ActionViewMixin, generics.GenericAPIView): """ Use this endpoint to obtain user authentication token. """ serializer_class = settings.SERIALIZERS.token_create permission_classes = settings.PERMISSIONS.token_create def _action(self, serializer): token = utils.login_user(self.request, serializer.user) token_serializer_class = settings.SERIALIZERS.token return Response( data=token_serializer_class(token).data, status=status.HTTP_200_OK ) class TokenDestroyView(views.APIView): """ Use this endpoint to logout user (remove user authentication token). """ permission_classes = settings.PERMISSIONS.token_destroy def post(self, request): utils.logout_user(request) return Response(status=status.HTTP_204_NO_CONTENT) class UserViewSet(viewsets.ModelViewSet): serializer_class = settings.SERIALIZERS.user queryset = User.objects.all() permission_classes = settings.PERMISSIONS.user token_generator = default_token_generator lookup_field = settings.USER_ID_FIELD def permission_denied(self, request, **kwargs): if ( settings.HIDE_USERS and request.user.is_authenticated and self.action in ["update", "partial_update", "list", "retrieve"] ): raise NotFound() super().permission_denied(request, **kwargs) def get_queryset(self): user = self.request.user queryset = super().get_queryset() if settings.HIDE_USERS and self.action == "list" and not user.is_staff: queryset = queryset.filter(pk=user.pk) return queryset def get_permissions(self): if self.action == "create": self.permission_classes = settings.PERMISSIONS.user_create elif self.action == "activation": self.permission_classes = settings.PERMISSIONS.activation elif self.action == "resend_activation": self.permission_classes = settings.PERMISSIONS.password_reset elif self.action == "list": self.permission_classes = settings.PERMISSIONS.user_list elif self.action == "reset_password": self.permission_classes = settings.PERMISSIONS.password_reset elif self.action == "reset_password_confirm": self.permission_classes = settings.PERMISSIONS.password_reset_confirm elif self.action == "set_password": self.permission_classes = settings.PERMISSIONS.set_password elif self.action == "set_username": self.permission_classes = settings.PERMISSIONS.set_username elif self.action == "reset_username": self.permission_classes = settings.PERMISSIONS.username_reset elif self.action == "reset_username_confirm": self.permission_classes = settings.PERMISSIONS.username_reset_confirm elif self.action == "destroy" or ( self.action == "me" and self.request and self.request.method == "DELETE" ): self.permission_classes = settings.PERMISSIONS.user_delete return super().get_permissions() def get_serializer_class(self): if self.action == "create": if settings.USER_CREATE_PASSWORD_RETYPE: return settings.SERIALIZERS.user_create_password_retype return settings.SERIALIZERS.user_create elif self.action == "destroy" or ( self.action == "me" and self.request and self.request.method == "DELETE" ): return settings.SERIALIZERS.user_delete elif self.action == "activation": return settings.SERIALIZERS.activation elif self.action == "resend_activation": return settings.SERIALIZERS.password_reset elif self.action == "reset_password": return settings.SERIALIZERS.password_reset elif self.action == "reset_password_confirm": if settings.PASSWORD_RESET_CONFIRM_RETYPE: return settings.SERIALIZERS.password_reset_confirm_retype return settings.SERIALIZERS.password_reset_confirm elif self.action == "set_password": if settings.SET_PASSWORD_RETYPE: return settings.SERIALIZERS.set_password_retype return settings.SERIALIZERS.set_password elif self.action == "set_username": if settings.SET_USERNAME_RETYPE: return settings.SERIALIZERS.set_username_retype return settings.SERIALIZERS.set_username elif self.action == "reset_username": return settings.SERIALIZERS.username_reset elif self.action == "reset_username_confirm": if settings.USERNAME_RESET_CONFIRM_RETYPE: return settings.SERIALIZERS.username_reset_confirm_retype return settings.SERIALIZERS.username_reset_confirm elif self.action == "me": return settings.SERIALIZERS.current_user return self.serializer_class def get_instance(self): return self.request.user def perform_create(self, serializer): user = serializer.save() signals.user_registered.send( sender=self.__class__, user=user, request=self.request ) context = {"user": user} to = [get_user_email(user)] if settings.SEND_ACTIVATION_EMAIL: settings.EMAIL.activation(self.request, context).send(to) elif settings.SEND_CONFIRMATION_EMAIL: settings.EMAIL.confirmation(self.request, context).send(to) def perform_update(self, serializer): super().perform_update(serializer) user = serializer.instance # should we send activation email after update? if settings.SEND_ACTIVATION_EMAIL: context = {"user": user} to = [get_user_email(user)] settings.EMAIL.activation(self.request, context).send(to) def destroy(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance, data=request.data) serializer.is_valid(raise_exception=True) if instance == request.user: utils.logout_user(self.request) self.perform_destroy(instance) return Response(status=status.HTTP_204_NO_CONTENT) @action(["get", "put", "patch", "delete"], detail=False) def me(self, request, *args, **kwargs): self.get_object = self.get_instance if request.method == "GET": return self.retrieve(request, *args, **kwargs) elif request.method == "PUT": return self.update(request, *args, **kwargs) elif request.method == "PATCH": return self.partial_update(request, *args, **kwargs) elif request.method == "DELETE": return self.destroy(request, *args, **kwargs) @action(["post"], detail=False) def activation(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = serializer.user user.is_active = True user.save() signals.user_activated.send( sender=self.__class__, user=user, request=self.request ) if settings.SEND_CONFIRMATION_EMAIL: context = {"user": user} to = [get_user_email(user)] settings.EMAIL.confirmation(self.request, context).send(to) return Response(status=status.HTTP_204_NO_CONTENT) @action(["post"], detail=False) def resend_activation(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = serializer.get_user(is_active=False) if not settings.SEND_ACTIVATION_EMAIL or not user: return Response(status=status.HTTP_400_BAD_REQUEST) context = {"user": user} to = [get_user_email(user)] settings.EMAIL.activation(self.request, context).send(to) return Response(status=status.HTTP_204_NO_CONTENT) @action(["post"], detail=False) def set_password(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.request.user.set_password(serializer.data["new_password"]) self.request.user.save() if settings.PASSWORD_CHANGED_EMAIL_CONFIRMATION: context = {"user": self.request.user} to = [get_user_email(self.request.user)] settings.EMAIL.password_changed_confirmation(self.request, context).send(to) if settings.LOGOUT_ON_PASSWORD_CHANGE: utils.logout_user(self.request) elif settings.CREATE_SESSION_ON_LOGIN: update_session_auth_hash(self.request, self.request.user) return Response(status=status.HTTP_204_NO_CONTENT) @action(["post"], detail=False) def reset_password(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = serializer.get_user() if user: context = {"user": user} to = [get_user_email(user)] settings.EMAIL.password_reset(self.request, context).send(to) return Response(status=status.HTTP_204_NO_CONTENT) @action(["post"], detail=False) def reset_password_confirm(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.user.set_password(serializer.data["new_password"]) if hasattr(serializer.user, "last_login"): serializer.user.last_login = now() serializer.user.save() if settings.PASSWORD_CHANGED_EMAIL_CONFIRMATION: context = {"user": serializer.user} to = [get_user_email(serializer.user)] settings.EMAIL.password_changed_confirmation(self.request, context).send(to) return Response(status=status.HTTP_204_NO_CONTENT) @action(["post"], detail=False, url_path="set_{}".format(User.USERNAME_FIELD)) def set_username(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = self.request.user new_username = serializer.data["new_" + User.USERNAME_FIELD] setattr(user, User.USERNAME_FIELD, new_username) user.save() if settings.USERNAME_CHANGED_EMAIL_CONFIRMATION: context = {"user": user} to = [get_user_email(user)] settings.EMAIL.username_changed_confirmation(self.request, context).send(to) return Response(status=status.HTTP_204_NO_CONTENT) @action(["post"], detail=False, url_path="reset_{}".format(User.USERNAME_FIELD)) def reset_username(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = serializer.get_user() if user: context = {"user": user} to = [get_user_email(user)] settings.EMAIL.username_reset(self.request, context).send(to) return Response(status=status.HTTP_204_NO_CONTENT) @action( ["post"], detail=False, url_path="reset_{}_confirm".format(User.USERNAME_FIELD) ) def reset_username_confirm(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) new_username = serializer.data["new_" + User.USERNAME_FIELD] setattr(serializer.user, User.USERNAME_FIELD, new_username) if hasattr(serializer.user, "last_login"): serializer.user.last_login = now() serializer.user.save() if settings.USERNAME_CHANGED_EMAIL_CONFIRMATION: context = {"user": serializer.user} to = [get_user_email(serializer.user)] settings.EMAIL.username_changed_confirmation(self.request, context).send(to) return Response(status=status.HTTP_204_NO_CONTENT) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1603449460.3570068 djoser-2.1.0/pyproject.toml0000644000000000000000000000471400000000000012611 0ustar00[tool.poetry] name = "djoser" version = "2.1.0" description = "REST implementation of Django authentication system." authors = [ "Sunscrapers ", ] maintainers = [ "Tomasz Wójcik ", "Dominik Kozaczko ", ] license = "MIT" classifiers = [ "Development Status :: 5 - Production/Stable", "Framework :: Django", "Framework :: Django :: 2.2", "Framework :: Django :: 3.1", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", ] repository = "https://github.com/sunscrapers/djoser" documentation = "https://djoser.readthedocs.io/" readme = "README.rst" include = ["djoser/locale/**/*.mo"] [tool.poetry.dependencies] python = "^3.6.1" importlib-metadata = {version = "^1.0", python = "<3.8"} djangorestframework-simplejwt = "^4.3.0" django-templated-mail = "^1.1.1" social-auth-app-django = "^4.0.0" coreapi = "^2.3.3" asgiref = "^3.2.10" pytest = {version = "^6.0.2", optional=true} codecov = {version="^2.0.16", optional=true} coverage = {version="^5.3", optional=true} pytest-cov = {version="^2.10.1", optional=true} pytest-django = {version="^3.10.0", optional=true} pytest-pythonpath = {version="^0.7.3", optional=true} djet = {version="^0.2.2", optional=true} [tool.poetry.dev-dependencies] pre-commit = "^2.7.1" tox = "^3.20.0" babel = "^2.8.0" black = "^20.8b1" [tool.poetry.extras] test = [ "pytest", "codecov", "coverage", "pytest-cov", "pytest-django", "pytest-pythonpath", "djet", ] [tool.black] line-length = 88 target-version = ['py36'] include = '\.pyi?$' exclude = ''' ( /( \.cache | \.eggs | \.git | \.hg | \.mypy_cache | \.pytest_cache | \.tox | \.venv | __pycache__ | _build | buck-out | build | dist | docs | migrations )/ ) ''' [tool.isort] profile = "black" [tool.pytest.ini_options] minversion = "6.0" DJANGO_SETTINGS_MODULE = "testproject.settings" python_paths = "testproject" [tool.pylint.messages_control] disable = "C0330, C0326" [tool.pylint.format] max-line-length = "88" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1604072747.271414 djoser-2.1.0/setup.py0000644000000000000000000001467600000000000011417 0ustar00# -*- coding: utf-8 -*- from setuptools import setup packages = \ ['djoser', 'djoser.social', 'djoser.social.backends', 'djoser.social.token', 'djoser.urls'] package_data = \ {'': ['*'], 'djoser': ['locale/de/LC_MESSAGES/django.po', 'locale/es/LC_MESSAGES/django.po', 'locale/fr/LC_MESSAGES/django.po', 'locale/ka/LC_MESSAGES/django.po', 'locale/pl/LC_MESSAGES/django.po', 'locale/pt_BR/LC_MESSAGES/django.po', 'locale/ru_RU/LC_MESSAGES/django.po', 'templates/email/*']} install_requires = \ ['asgiref>=3.2.10,<4.0.0', 'coreapi>=2.3.3,<3.0.0', 'django-templated-mail>=1.1.1,<2.0.0', 'djangorestframework-simplejwt>=4.3.0,<5.0.0', 'social-auth-app-django>=4.0.0,<5.0.0'] extras_require = \ {':python_version < "3.8"': ['importlib-metadata>=1.0,<2.0'], 'test': ['pytest>=6.0.2,<7.0.0', 'codecov>=2.0.16,<3.0.0', 'coverage>=5.3,<6.0', 'pytest-cov>=2.10.1,<3.0.0', 'pytest-django>=3.10.0,<4.0.0', 'pytest-pythonpath>=0.7.3,<0.8.0', 'djet>=0.2.2,<0.3.0']} setup_kwargs = { 'name': 'djoser', 'version': '2.1.0', 'description': 'REST implementation of Django authentication system.', 'long_description': '======\ndjoser\n======\n\n.. image:: https://img.shields.io/pypi/v/djoser.svg\n :target: https://pypi.org/project/djoser\n\n.. image:: https://img.shields.io/travis/sunscrapers/djoser/master.svg\n :target: https://travis-ci.org/sunscrapers/djoser\n\n.. image:: https://img.shields.io/codecov/c/github/sunscrapers/djoser.svg\n :target: https://codecov.io/gh/sunscrapers/djoser\n\n.. image:: https://api.codacy.com/project/badge/Grade/c9bf80318d2741e5bb63912a5e0b32dc\n :alt: Codacy Badge\n :target: https://app.codacy.com/app/dekoza/djoser?utm_source=github.com&utm_medium=referral&utm_content=sunscrapers/djoser&utm_campaign=Badge_Grade_Dashboard\n\n.. image:: https://img.shields.io/pypi/dm/djoser\n :target: https://img.shields.io/pypi/dm/djoser\n\n\nREST implementation of `Django `_ authentication\nsystem. **djoser** library provides a set of `Django Rest Framework `_\nviews to handle basic actions such as registration, login, logout, password\nreset and account activation. It works with\n`custom user model `_.\n\nInstead of reusing Django code (e.g. ``PasswordResetForm``), we reimplemented\nfew things to fit better into `Single Page App `_\narchitecture.\n\nDeveloped by `SUNSCRAPERS `_ with passion & patience.\n\n.. image:: https://asciinema.org/a/94J4eG2tSBD2iEfF30a6vGtXw.png\n :target: https://asciinema.org/a/94J4eG2tSBD2iEfF30a6vGtXw\n\nRequirements\n============\n\nTo be able to run **djoser** you have to meet following requirements:\n\n- Python (3.6, 3.7, 3.8, 3.9)\n- Django (2.2, 3.1)\n- Django REST Framework 3.11.1\n\nIf you need to support other versions, please use djoser<2.\n\nInstallation\n============\n\nSimply install using ``pip``:\n\n.. code-block:: bash\n\n $ pip install djoser\n\nAnd continue with the steps described at\n`configuration `_\nguide.\n\nDocumentation\n=============\n\nDocumentation is available to study at\n`https://djoser.readthedocs.io `_\nand in ``docs`` directory.\n\nContributing and development\n============================\n\nTo start developing on **djoser**, clone the repository:\n\n.. code-block:: bash\n\n $ git clone git@github.com:sunscrapers/djoser.git\n\nWe use `poetry `_ as dependency management and packaging tool.\n\n.. code-block:: bash\n\n $ cd djoser\n $ poetry install -E test\n\nThis will create a virtualenv with all development dependencies.\n\nTo run the test just type:\n\n.. code-block:: bash\n\n $ poetry run py.test testproject\n\nWe also preapred a convenient ``Makefile`` to automate commands above:\n\n.. code-block:: bash\n\n $ make init\n $ make test\n\nTo activate the virtual environment run\n\n.. code-block:: bash\n\n $ poetry shell\n\nWithout poetry\n--------------\n\nNew versions of ``pip`` can use ``pyproject.toml`` to build the package and install its dependencies.\n\n.. code-block:: bash\n\n $ pip install .[test]\n\n.. code-block:: bash\n\n $ cd testproject\n $ ./manage.py test\n\nTox\n---\n\nIf you need to run tests against all supported Python and Django versions then invoke:\n\n.. code-block:: bash\n\n $ poetry run tox -p all\n\nExample project\n---------------\n\nYou can also play with test project by running following commands:\n\n.. code-block:: bash\n\n $ make migrate\n $ make runserver\n\nCommiting your code\n-------------------\n\nBefore sending patches please make sure you have `pre-commit `_ activated in your local git repository:\n\n.. code-block:: bash\n\n $ pre-commit install\n\nThis will ensure that your code is cleaned before you commit it.\nSome steps (like black) automatically fix issues but the show their status as FAILED.\nJust inspect if eveything is OK, git-add the files and retry the commit.\nOther tools (like flake8) require you to manually fix the issues.\n\n\nSimilar projects\n================\n\nList of projects related to Django, REST and authentication:\n\n- `django-rest-framework-simplejwt `_\n- `django-oauth-toolkit `_\n- `django-rest-auth `_ (not maintained)\n- `django-rest-framework-digestauth `_ (not maintained)\n\nPlease, keep in mind that while using custom authentication and TokenCreateSerializer\nvalidation, there is a path that **ignores intentional return of None** from authenticate()\nand try to find User using parameters. Probably, that will be changed in the future.\n', 'author': 'Sunscrapers', 'author_email': 'info@sunscrapers.com', 'maintainer': 'Tomasz Wójcik', 'maintainer_email': 't.wojcik@sunscrapers.com', 'url': 'https://github.com/sunscrapers/djoser', 'packages': packages, 'package_data': package_data, 'install_requires': install_requires, 'extras_require': extras_require, 'python_requires': '>=3.6.1,<4.0.0', } setup(**setup_kwargs) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1604072747.2719822 djoser-2.1.0/PKG-INFO0000644000000000000000000001466200000000000010775 0ustar00Metadata-Version: 2.1 Name: djoser Version: 2.1.0 Summary: REST implementation of Django authentication system. Home-page: https://github.com/sunscrapers/djoser License: MIT Author: Sunscrapers Author-email: info@sunscrapers.com Maintainer: Tomasz Wójcik Maintainer-email: t.wojcik@sunscrapers.com Requires-Python: >=3.6.1,<4.0.0 Classifier: Development Status :: 5 - Production/Stable Classifier: Framework :: Django Classifier: Framework :: Django :: 2.2 Classifier: Framework :: Django :: 3.1 Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Provides-Extra: test Requires-Dist: asgiref (>=3.2.10,<4.0.0) Requires-Dist: codecov (>=2.0.16,<3.0.0); extra == "test" Requires-Dist: coreapi (>=2.3.3,<3.0.0) Requires-Dist: coverage (>=5.3,<6.0); extra == "test" Requires-Dist: django-templated-mail (>=1.1.1,<2.0.0) Requires-Dist: djangorestframework-simplejwt (>=4.3.0,<5.0.0) Requires-Dist: djet (>=0.2.2,<0.3.0); extra == "test" Requires-Dist: importlib-metadata (>=1.0,<2.0); python_version < "3.8" Requires-Dist: pytest (>=6.0.2,<7.0.0); extra == "test" Requires-Dist: pytest-cov (>=2.10.1,<3.0.0); extra == "test" Requires-Dist: pytest-django (>=3.10.0,<4.0.0); extra == "test" Requires-Dist: pytest-pythonpath (>=0.7.3,<0.8.0); extra == "test" Requires-Dist: social-auth-app-django (>=4.0.0,<5.0.0) Project-URL: Documentation, https://djoser.readthedocs.io/ Project-URL: Repository, https://github.com/sunscrapers/djoser Description-Content-Type: text/x-rst ====== djoser ====== .. image:: https://img.shields.io/pypi/v/djoser.svg :target: https://pypi.org/project/djoser .. image:: https://img.shields.io/travis/sunscrapers/djoser/master.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://api.codacy.com/project/badge/Grade/c9bf80318d2741e5bb63912a5e0b32dc :alt: Codacy Badge :target: https://app.codacy.com/app/dekoza/djoser?utm_source=github.com&utm_medium=referral&utm_content=sunscrapers/djoser&utm_campaign=Badge_Grade_Dashboard .. image:: https://img.shields.io/pypi/dm/djoser :target: https://img.shields.io/pypi/dm/djoser 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. .. image:: https://asciinema.org/a/94J4eG2tSBD2iEfF30a6vGtXw.png :target: https://asciinema.org/a/94J4eG2tSBD2iEfF30a6vGtXw Requirements ============ To be able to run **djoser** you have to meet following requirements: - Python (3.6, 3.7, 3.8, 3.9) - Django (2.2, 3.1) - Django REST Framework 3.11.1 If you need to support other versions, please use djoser<2. Installation ============ Simply install using ``pip``: .. code-block:: bash $ pip install djoser And continue with the steps described at `configuration `_ guide. Documentation ============= Documentation is available to study at `https://djoser.readthedocs.io `_ and in ``docs`` directory. Contributing and development ============================ To start developing on **djoser**, clone the repository: .. code-block:: bash $ git clone git@github.com:sunscrapers/djoser.git We use `poetry `_ as dependency management and packaging tool. .. code-block:: bash $ cd djoser $ poetry install -E test This will create a virtualenv with all development dependencies. To run the test just type: .. code-block:: bash $ poetry run py.test testproject We also preapred a convenient ``Makefile`` to automate commands above: .. code-block:: bash $ make init $ make test To activate the virtual environment run .. code-block:: bash $ poetry shell Without poetry -------------- New versions of ``pip`` can use ``pyproject.toml`` to build the package and install its dependencies. .. code-block:: bash $ pip install .[test] .. code-block:: bash $ cd testproject $ ./manage.py test Tox --- If you need to run tests against all supported Python and Django versions then invoke: .. code-block:: bash $ poetry run tox -p all Example project --------------- You can also play with test project by running following commands: .. code-block:: bash $ make migrate $ make runserver Commiting your code ------------------- Before sending patches please make sure you have `pre-commit `_ activated in your local git repository: .. code-block:: bash $ pre-commit install This will ensure that your code is cleaned before you commit it. Some steps (like black) automatically fix issues but the show their status as FAILED. Just inspect if eveything is OK, git-add the files and retry the commit. Other tools (like flake8) require you to manually fix the issues. Similar projects ================ List of projects related to Django, REST and authentication: - `django-rest-framework-simplejwt `_ - `django-oauth-toolkit `_ - `django-rest-auth `_ (not maintained) - `django-rest-framework-digestauth `_ (not maintained) Please, keep in mind that while using custom authentication and TokenCreateSerializer validation, there is a path that **ignores intentional return of None** from authenticate() and try to find User using parameters. Probably, that will be changed in the future.