# Garpix User
Auth module for Django/DRF projects. Part of GarpixCMS.
Used packages:
* [django rest framework](https://www.django-rest-framework.org/api-guide/authentication/)
* [social-auth-app-django](https://github.com/python-social-auth/social-app-django)
* [django-rest-framework-social-oauth2](https://github.com/RealmTeam/django-rest-framework-social-oauth2)
* etc; see setup.py
## Quickstart
Install with pip:
```bash
pip install garpix_user
```
Add the `garpix_user` to your `INSTALLED_APPS`:
```python
# settings.py
# ...
INSTALLED_APPS = [
# ...
'garpix_user',
]
```
and to migration modules:
```python
# settings.py
# ...
MIGRATION_MODULES = {
'garpix_user': 'app.migrations.garpix_user',
}
```
Add to `urls.py`:
```python
from garpix_user.views import LogoutView, LoginView
# ...
urlpatterns = [
# ...
# garpix_user
path('', include(('garpix_user.urls', 'user'), namespace='garpix_user')),
path('logout/', LogoutView.as_view(url='/'), name="logout"),
path('login/', LoginView.as_view(template_name="accounts/login.html"), name="authorize"),
]
```
Use `GarpixUser` from `garpix_user.models` as base for your user model class:
```python
# user.models.user.py
from garpix_user.models import GarpixUser
class User(GarpixUser):
class Meta:
verbose_name = 'Пользователь'
verbose_name_plural = 'Пользователи'
def __str__(self):
return self.username
```
Use `UserAdmin` from `garpix_user.admin` as base for your user admin class:
```python
from django.contrib import admin
from garpix_user.admin import UserAdmin
from user.models import User
@admin.register(User)
class UserAdmin(UserAdmin):
pass
```
For custom auth with phone and/or email use this in `settings.py`:
```python
# ...
AUTHENTICATION_BACKENDS = (
# Django
'garpix_user.utils.backends.CustomAuthenticationBackend'
)
```
and `USERNAME_FIELDS` to your `User` model:
```python
# user.models.user.py
from garpix_user.models import GarpixUser
class User(GarpixUser):
USERNAME_FIELDS = ('email', ) # default is username
class Meta:
verbose_name = 'Пользователь'
verbose_name_plural = 'Пользователи'
def __str__(self):
return self.username
```
## With Django Rest Framework
Import settings from `garpix_user`:
```python
# settings.py
from garpix_user.settings import *
```
Add this for SPA:
```python
# ...
INSTALLED_APPS += [
# ...
'rest_framework',
'rest_framework.authtoken',
'oauth2_provider',
'social_django',
'rest_framework_social_oauth2',
# ...
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': {
'garpix_user.rest.authentication.MainAuthentication',
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
'rest_framework_social_oauth2.authentication.SocialAuthentication',
}
}
```
### JWT Token
You can use JWT token. To do it set `REST_AUTH_TOKEN_JWT` settings to True. You also need to
set `JWT_SECRET_KEY`, `JWT_SERIALIZER` settings:
```python
# settings.py
# ...
GARPIX_USER = {
'REST_AUTH_TOKEN_JWT': True,
'JWT_SECRET_KEY': env('JWT_SECRET_KEY'), # secret code to validate JWT token
'JWT_SERIALIZER': 'garpix_user.serializers.JWTDataSerializer'
}
# Hint: see all available settings in the end of this document.
```
### Authorization headers
You can override the Bearer authorization header by `REST_AUTH_HEADER_KEY` setting.
And also allow this custom header for cors-headers:
```python
# settings.py
# ...
from corsheaders.defaults import default_headers
GARPIX_USER = {
'REST_AUTH_HEADER_KEY': 'HTTP_BEARER_AUTHORIZATION'
}
# Hint: see all available settings in the end of this document.
CORS_ALLOW_HEADERS = list(default_headers) + [
"Bearer-Authorization",
]
```
Now you need to add `Bearer-Authorization` header instead of `Authorization` header with your Bearer token to all
requests.
## Registration
`garpix_user` adds default registration for with `phone` and/or `email` and `password` fields. To add fields to this form override `RegistrationSerializer` and add it to `settings`:
```python
# settings.py
GARPIX_USER = {
# registration
'REGISTRATION_SERIALIZER': 'app.serializers.RegistrationCustSerializer'
}
# Hint: see all available settings in the end of this document.
```
```python
# app.serializers.py
from django.contrib.auth import get_user_model
from rest_framework import serializers
from garpix_user.serializers import RegistrationSerializer
User = get_user_model()
class RegistrationCustSerializer(RegistrationSerializer):
extra_field = serializers.CharField(write_only=True)
class Meta(RegistrationSerializer.Meta):
model = User
fields = RegistrationSerializer.Meta.fields + ('extra_field',)
```
You also can add password security settings:
```python
# settings.py
GARPIX_USER = {
# registration
'MIN_LENGTH_PASSWORD': 8,
'MIN_DIGITS_PASSWORD': 2,
'MIN_CHARS_PASSWORD': 2,
'MIN_UPPERCASE_PASSWORD': 1,
}
# Hint: see all available settings in the end of this document.
```
## Email and phone confirmation, password restoring
To use email and phone confirmation or (and) restore password functionality add the `garpix_notify` to your `INSTALLED_APPS`:
```python
# settings.py
# ...
INSTALLED_APPS = [
# ...
'garpix_notify',
]
```
and to migration modules:
```python
# settings.py
MIGRATION_MODULES = {
'garpix_notify': 'app.migrations.garpix_notify',
}
```
Add corresponding settings:
```python
# settings.py
GARPIX_USER = {
'USE_EMAIL_CONFIRMATION': True,
'USE_PHONE_CONFIRMATION': True,
'USE_EMAIL_RESTORE_PASSWORD': True,
'USE_PHONE_RESTORE_PASSWORD': True,
}
# Hint: see all available settings in the end of this document.
```
You also need to add notify events:
```python
# settings.py
NOTIFY_EVENTS.update(GARPIX_USER_NOTIFY_EVENTS)
```
You can specify email and phone code length, lifetime, confirmation lifetime and time delay before next attempt:
```python
#settings.py
GARPIX_USER = {
'CONFIRM_PHONE_CODE_LENGTH': 6,
'CONFIRM_EMAIL_CODE_LENGTH': 6,
'TIME_LAST_REQUEST': 1,
'CONFIRM_PHONE_CODE_LIFE_TIME': 5, # in minutes
'CONFIRM_EMAIL_CODE_LIFE_TIME': 2,
'CONFIRM_EMAIL_CODE_LIFE_TIME_TYPE': 'days', # available types are: ['days', 'minutes'], default is 'days'
'PHONE_CONFIRMATION_LIFE_TIME': 2, # in days
'EMAIL_CONFIRMATION_LIFE_TIME': 2, # in days
}
# Hint: see all available settings in the end of this document.
```
Notice: the minimum and maximum values for `CONFIRM_CODE_LENGTH` are 4 and 255. These values will be hard used in case your settings are not in this interval.
If you need to use pre-registration email or phone confirmation, you need to set corresponding variables to True:
```python
# settings.py
GARPIX_USER = {
'USE_PREREGISTRATION_EMAIL_CONFIRMATION': True,
'USE_PREREGISTRATION_PHONE_CONFIRMATION': True,
}
# Hint: see all available settings in the end of this document.
```
If you need to use email confirmation by link, you need to set corresponding variable:
```python
# settings.py
GARPIX_USER = {
'USE_EMAIL_LINK_CONFIRMATION': True
}
# Hint: see all available settings in the end of this document.
```
You can also override `confirm_link_redirect_url` method of `User` model to form confirmation link as you need.
By default, users with unconfirmed email/phone number will be deleted in 10 days. You can set up it using `CONFIRMATION_DELAY`:
```python
# settings.py
GARPIX_USER = {
# ...
'CONFIRMATION_DELAY': 10, # in days
}
# Hint: see all available settings in the end of this document.
```
## Referral links
You can also use referral links in your project with garpix_user. To add this functionality, just add the corresponding settings:
```python
# settings.py
GARPIX_USER = {
'USE_REFERRAL_LINKS': True,
'REFERRAL_REDIRECT_URL': '/', # link to the page user needs to see
}
# Hint: see all available settings in the end of this document.
```
## UserSession
Using `garpix_user` you can also store info about unregistered user sessions. The package already consists of model and views for it.
To create the unregistered user send `POST` request to `{API_URL}/user_session/create_user_session/`
The request returns `UserSession` object with `token_number` field. You need to send this token number in each request passing in to header as `user-session-token`.
By default, on log in current user session instance will be dropped, if system has `registered` user session instance for authorized user. You can override `set_user_session` method of `User` model to add custom logic.
## All available settings with default values
```python
# settings.py
GARPIX_USER = {
# base settings
'USE_REFERRAL_LINKS': False,
'REFERRAL_REDIRECT_URL': '/',
# email/phone confirmation
'USE_EMAIL_CONFIRMATION': True,
'USE_PHONE_CONFIRMATION': True,
'USE_PREREGISTRATION_EMAIL_CONFIRMATION': True,
'USE_PREREGISTRATION_PHONE_CONFIRMATION': True,
'USE_EMAIL_LINK_CONFIRMATION': True,
'CONFIRM_PHONE_CODE_LENGTH': 6,
'CONFIRM_EMAIL_CODE_LENGTH': 6,
'TIME_LAST_REQUEST': 1,
'CONFIRM_PHONE_CODE_LIFE_TIME': 5, # in minutes
'CONFIRM_EMAIL_CODE_LIFE_TIME': 2,
'CONFIRM_EMAIL_CODE_LIFE_TIME_TYPE': 'days',
'PHONE_CONFIRMATION_LIFE_TIME': 2, # in days
'EMAIL_CONFIRMATION_LIFE_TIME': 2, # in days
'CONFIRMATION_DELAY': 10, # in days
# restore password
'USE_RESTORE_PASSWORD': True,
# registration
'USE_REGISTRATION': True,
'REGISTRATION_SERIALIZER': 'app.serializers.RegistrationCustSerializer',
'MIN_LENGTH_PASSWORD': 8,
'MIN_DIGITS_PASSWORD': 2,
'MIN_CHARS_PASSWORD': 2,
'MIN_UPPERCASE_PASSWORD': 1,
# authorization
'REST_AUTH_HEADER_KEY': 'HTTP_AUTHORIZATION',
'REST_AUTH_TOKEN_JWT': False,
'JWT_SERIALIZER': 'garpix_user.serializers.JWTDataSerializer',
# response messages
'WAIT_RESPONSE': 'Не прошло 1 мин с момента предыдущего запроса',
'USER_REGISTERED_RESPONSE': 'Пользователь с таким {field} уже зарегистрирован', # as 'field' will be used email/phone according to the request
'INCORRECT_CODE_RESPONSE': 'Некорретный код',
'NO_TIME_LEFT_RESPONSE': 'Код недействителен. Запросите повторно',
'NOT_AUTHENTICATED_RESPONSE': 'Учетные данные не были предоставлены'
}
```
See `garpix_user/tests/test_api/*.py` for examples.
# Changelog
See [CHANGELOG.md](CHANGELOG.md).
# Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md).
# License
[MIT](LICENSE)
---
Developed by Garpix / [https://garpix.com](https://garpix.com)
Raw data
{
"_id": null,
"home_page": "https://github.com/garpixcms/garpix_user",
"name": "garpix-user",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "",
"author": "Garpix LTD",
"author_email": "info@garpix.com",
"download_url": "https://files.pythonhosted.org/packages/11/5b/45fff65aaad412c9c54827cb821254c10580683d933f5bff40146aa6a594/garpix_user-3.9.1.tar.gz",
"platform": null,
"description": "# Garpix User\n\nAuth module for Django/DRF projects. Part of GarpixCMS.\n\nUsed packages: \n\n* [django rest framework](https://www.django-rest-framework.org/api-guide/authentication/)\n* [social-auth-app-django](https://github.com/python-social-auth/social-app-django)\n* [django-rest-framework-social-oauth2](https://github.com/RealmTeam/django-rest-framework-social-oauth2)\n* etc; see setup.py\n\n## Quickstart\n\nInstall with pip:\n\n```bash\npip install garpix_user\n```\n\nAdd the `garpix_user` to your `INSTALLED_APPS`:\n\n```python\n# settings.py\n\n# ...\nINSTALLED_APPS = [\n # ...\n 'garpix_user',\n]\n```\n\nand to migration modules:\n\n```python\n# settings.py\n\n# ...\nMIGRATION_MODULES = {\n 'garpix_user': 'app.migrations.garpix_user',\n}\n```\n\nAdd to `urls.py`:\n\n```python\nfrom garpix_user.views import LogoutView, LoginView\n\n# ...\nurlpatterns = [\n # ...\n # garpix_user\n path('', include(('garpix_user.urls', 'user'), namespace='garpix_user')),\n path('logout/', LogoutView.as_view(url='/'), name=\"logout\"),\n path('login/', LoginView.as_view(template_name=\"accounts/login.html\"), name=\"authorize\"),\n]\n```\n\nUse `GarpixUser` from `garpix_user.models` as base for your user model class:\n\n```python\n# user.models.user.py\n\nfrom garpix_user.models import GarpixUser\n\n\nclass User(GarpixUser):\n \n class Meta:\n verbose_name = '\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c'\n verbose_name_plural = '\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438'\n\n def __str__(self):\n return self.username\n\n```\n\nUse `UserAdmin` from `garpix_user.admin` as base for your user admin class:\n\n```python\n\nfrom django.contrib import admin\n\nfrom garpix_user.admin import UserAdmin\nfrom user.models import User\n\n\n@admin.register(User)\nclass UserAdmin(UserAdmin):\n pass\n\n```\n\nFor custom auth with phone and/or email use this in `settings.py`:\n\n```python\n# ...\n\nAUTHENTICATION_BACKENDS = (\n # Django\n 'garpix_user.utils.backends.CustomAuthenticationBackend'\n)\n\n```\n\nand `USERNAME_FIELDS` to your `User` model:\n\n```python\n# user.models.user.py\n\nfrom garpix_user.models import GarpixUser\n\n\nclass User(GarpixUser):\n \n USERNAME_FIELDS = ('email', ) # default is username\n \n class Meta:\n verbose_name = '\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c'\n verbose_name_plural = '\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438'\n\n def __str__(self):\n return self.username\n\n```\n\n## With Django Rest Framework\n\nImport settings from `garpix_user`:\n\n```python\n# settings.py\nfrom garpix_user.settings import *\n\n```\n\nAdd this for SPA:\n\n```python\n# ...\nINSTALLED_APPS += [\n # ...\n 'rest_framework',\n 'rest_framework.authtoken',\n 'oauth2_provider',\n 'social_django',\n 'rest_framework_social_oauth2',\n # ...\n]\n\nREST_FRAMEWORK = {\n 'DEFAULT_AUTHENTICATION_CLASSES': {\n 'garpix_user.rest.authentication.MainAuthentication',\n 'oauth2_provider.contrib.rest_framework.OAuth2Authentication',\n 'rest_framework_social_oauth2.authentication.SocialAuthentication',\n }\n}\n\n```\n### JWT Token\n\nYou can use JWT token. To do it set `REST_AUTH_TOKEN_JWT` settings to True. You also need to\nset `JWT_SECRET_KEY`, `JWT_SERIALIZER` settings:\n\n```python\n# settings.py\n\n# ...\n\nGARPIX_USER = {\n 'REST_AUTH_TOKEN_JWT': True,\n 'JWT_SECRET_KEY': env('JWT_SECRET_KEY'), # secret code to validate JWT token\n 'JWT_SERIALIZER': 'garpix_user.serializers.JWTDataSerializer'\n}\n\n# Hint: see all available settings in the end of this document.\n\n```\n\n### Authorization headers\n\nYou can override the Bearer authorization header by `REST_AUTH_HEADER_KEY` setting.\nAnd also allow this custom header for cors-headers:\n\n```python\n# settings.py\n\n# ...\nfrom corsheaders.defaults import default_headers\n\nGARPIX_USER = {\n 'REST_AUTH_HEADER_KEY': 'HTTP_BEARER_AUTHORIZATION'\n}\n\n# Hint: see all available settings in the end of this document.\n\nCORS_ALLOW_HEADERS = list(default_headers) + [\n \"Bearer-Authorization\",\n]\n```\n\nNow you need to add `Bearer-Authorization` header instead of `Authorization` header with your Bearer token to all\nrequests.\n\n## Registration\n\n`garpix_user` adds default registration for with `phone` and/or `email` and `password` fields. To add fields to this form override `RegistrationSerializer` and add it to `settings`:\n\n```python\n# settings.py\n\nGARPIX_USER = {\n # registration\n 'REGISTRATION_SERIALIZER': 'app.serializers.RegistrationCustSerializer'\n}\n\n# Hint: see all available settings in the end of this document.\n\n```\n\n```python\n# app.serializers.py\n\nfrom django.contrib.auth import get_user_model\nfrom rest_framework import serializers\n\nfrom garpix_user.serializers import RegistrationSerializer\n\nUser = get_user_model()\n\n\nclass RegistrationCustSerializer(RegistrationSerializer):\n extra_field = serializers.CharField(write_only=True)\n\n class Meta(RegistrationSerializer.Meta):\n model = User\n fields = RegistrationSerializer.Meta.fields + ('extra_field',)\n\n```\n\nYou also can add password security settings:\n\n```python\n\n# settings.py\n\nGARPIX_USER = {\n # registration\n 'MIN_LENGTH_PASSWORD': 8,\n 'MIN_DIGITS_PASSWORD': 2,\n 'MIN_CHARS_PASSWORD': 2,\n 'MIN_UPPERCASE_PASSWORD': 1,\n}\n\n# Hint: see all available settings in the end of this document.\n\n```\n\n## Email and phone confirmation, password restoring\n\nTo use email and phone confirmation or (and) restore password functionality add the `garpix_notify` to your `INSTALLED_APPS`:\n\n```python\n# settings.py\n\n# ...\nINSTALLED_APPS = [\n # ...\n 'garpix_notify',\n]\n```\nand to migration modules:\n\n```python\n# settings.py\n\nMIGRATION_MODULES = {\n 'garpix_notify': 'app.migrations.garpix_notify',\n}\n```\n\nAdd corresponding settings:\n\n```python\n\n# settings.py\n\nGARPIX_USER = {\n 'USE_EMAIL_CONFIRMATION': True,\n 'USE_PHONE_CONFIRMATION': True,\n 'USE_EMAIL_RESTORE_PASSWORD': True,\n 'USE_PHONE_RESTORE_PASSWORD': True,\n}\n\n# Hint: see all available settings in the end of this document.\n\n```\n\nYou also need to add notify events:\n\n```python\n# settings.py\n\nNOTIFY_EVENTS.update(GARPIX_USER_NOTIFY_EVENTS)\n\n```\n\nYou can specify email and phone code length, lifetime, confirmation lifetime and time delay before next attempt:\n```python\n#settings.py \n\nGARPIX_USER = {\n 'CONFIRM_PHONE_CODE_LENGTH': 6,\n 'CONFIRM_EMAIL_CODE_LENGTH': 6,\n 'TIME_LAST_REQUEST': 1,\n 'CONFIRM_PHONE_CODE_LIFE_TIME': 5, # in minutes\n 'CONFIRM_EMAIL_CODE_LIFE_TIME': 2,\n 'CONFIRM_EMAIL_CODE_LIFE_TIME_TYPE': 'days', # available types are: ['days', 'minutes'], default is 'days'\n 'PHONE_CONFIRMATION_LIFE_TIME': 2, # in days\n 'EMAIL_CONFIRMATION_LIFE_TIME': 2, # in days\n}\n\n# Hint: see all available settings in the end of this document.\n\n```\n\nNotice: the minimum and maximum values for `CONFIRM_CODE_LENGTH` are 4 and 255. These values will be hard used in case your settings are not in this interval.\n\nIf you need to use pre-registration email or phone confirmation, you need to set corresponding variables to True:\n```python\n\n# settings.py\n\nGARPIX_USER = {\n 'USE_PREREGISTRATION_EMAIL_CONFIRMATION': True,\n 'USE_PREREGISTRATION_PHONE_CONFIRMATION': True,\n}\n\n# Hint: see all available settings in the end of this document.\n\n```\n\nIf you need to use email confirmation by link, you need to set corresponding variable:\n```python\n\n# settings.py\n\nGARPIX_USER = {\n 'USE_EMAIL_LINK_CONFIRMATION': True\n}\n\n# Hint: see all available settings in the end of this document.\n\n```\n\nYou can also override `confirm_link_redirect_url` method of `User` model to form confirmation link as you need.\n\nBy default, users with unconfirmed email/phone number will be deleted in 10 days. You can set up it using `CONFIRMATION_DELAY`:\n\n```python\n# settings.py\n\nGARPIX_USER = {\n# ...\n 'CONFIRMATION_DELAY': 10, # in days\n}\n# Hint: see all available settings in the end of this document.\n\n```\n\n## Referral links\n\nYou can also use referral links in your project with garpix_user. To add this functionality, just add the corresponding settings:\n\n```python \n\n# settings.py\n\nGARPIX_USER = {\n 'USE_REFERRAL_LINKS': True,\n 'REFERRAL_REDIRECT_URL': '/', # link to the page user needs to see\n}\n# Hint: see all available settings in the end of this document.\n\n```\n\n## UserSession\n\nUsing `garpix_user` you can also store info about unregistered user sessions. The package already consists of model and views for it.\n\nTo create the unregistered user send `POST` request to `{API_URL}/user_session/create_user_session/`\n\nThe request returns `UserSession` object with `token_number` field. You need to send this token number in each request passing in to header as `user-session-token`.\n\nBy default, on log in current user session instance will be dropped, if system has `registered` user session instance for authorized user. You can override `set_user_session` method of `User` model to add custom logic.\n\n\n## All available settings with default values\n\n```python\n \n# settings.py\n\nGARPIX_USER = {\n # base settings\n 'USE_REFERRAL_LINKS': False,\n 'REFERRAL_REDIRECT_URL': '/',\n # email/phone confirmation\n 'USE_EMAIL_CONFIRMATION': True,\n 'USE_PHONE_CONFIRMATION': True,\n 'USE_PREREGISTRATION_EMAIL_CONFIRMATION': True,\n 'USE_PREREGISTRATION_PHONE_CONFIRMATION': True,\n 'USE_EMAIL_LINK_CONFIRMATION': True,\n 'CONFIRM_PHONE_CODE_LENGTH': 6,\n 'CONFIRM_EMAIL_CODE_LENGTH': 6,\n 'TIME_LAST_REQUEST': 1,\n 'CONFIRM_PHONE_CODE_LIFE_TIME': 5, # in minutes\n 'CONFIRM_EMAIL_CODE_LIFE_TIME': 2,\n 'CONFIRM_EMAIL_CODE_LIFE_TIME_TYPE': 'days',\n 'PHONE_CONFIRMATION_LIFE_TIME': 2, # in days\n 'EMAIL_CONFIRMATION_LIFE_TIME': 2, # in days\n 'CONFIRMATION_DELAY': 10, # in days\n # restore password\n 'USE_RESTORE_PASSWORD': True,\n # registration\n 'USE_REGISTRATION': True,\n 'REGISTRATION_SERIALIZER': 'app.serializers.RegistrationCustSerializer',\n 'MIN_LENGTH_PASSWORD': 8,\n 'MIN_DIGITS_PASSWORD': 2,\n 'MIN_CHARS_PASSWORD': 2,\n 'MIN_UPPERCASE_PASSWORD': 1,\n # authorization\n 'REST_AUTH_HEADER_KEY': 'HTTP_AUTHORIZATION',\n 'REST_AUTH_TOKEN_JWT': False,\n 'JWT_SERIALIZER': 'garpix_user.serializers.JWTDataSerializer',\n # response messages\n 'WAIT_RESPONSE': '\u041d\u0435 \u043f\u0440\u043e\u0448\u043b\u043e 1 \u043c\u0438\u043d \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430',\n 'USER_REGISTERED_RESPONSE': '\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c {field} \u0443\u0436\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d', # as 'field' will be used email/phone according to the request\n 'INCORRECT_CODE_RESPONSE': '\u041d\u0435\u043a\u043e\u0440\u0440\u0435\u0442\u043d\u044b\u0439 \u043a\u043e\u0434',\n 'NO_TIME_LEFT_RESPONSE': '\u041a\u043e\u0434 \u043d\u0435\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u0435\u043d. \u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e',\n 'NOT_AUTHENTICATED_RESPONSE': '\u0423\u0447\u0435\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u0431\u044b\u043b\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b'\n}\n\n```\n\nSee `garpix_user/tests/test_api/*.py` for examples.\n\n# Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md).\n\n# Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\n# License\n\n[MIT](LICENSE)\n\n---\n\nDeveloped by Garpix / [https://garpix.com](https://garpix.com)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "",
"version": "3.9.1",
"project_urls": {
"Homepage": "https://github.com/garpixcms/garpix_user"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "b66b773ba117b84f37624e0a1c222cfe0afe9c4d24d4f551ab9d33d298ae8c9a",
"md5": "7e941ecac713e5c90f0a051e785c73e8",
"sha256": "7f2ce316efa977ae37cd2dba7d0dd5ce2b8c85fd0306ae88d1baad95f6364e68"
},
"downloads": -1,
"filename": "garpix_user-3.9.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "7e941ecac713e5c90f0a051e785c73e8",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 64832,
"upload_time": "2023-08-29T07:33:26",
"upload_time_iso_8601": "2023-08-29T07:33:26.529297Z",
"url": "https://files.pythonhosted.org/packages/b6/6b/773ba117b84f37624e0a1c222cfe0afe9c4d24d4f551ab9d33d298ae8c9a/garpix_user-3.9.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "115b45fff65aaad412c9c54827cb821254c10580683d933f5bff40146aa6a594",
"md5": "b500caa3d145fa1d81f7b2e0215ad3db",
"sha256": "6e164b0f1cc6a58baaf20045e8528b22f461c41b7e7182112a1662ae463f474b"
},
"downloads": -1,
"filename": "garpix_user-3.9.1.tar.gz",
"has_sig": false,
"md5_digest": "b500caa3d145fa1d81f7b2e0215ad3db",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 39835,
"upload_time": "2023-08-29T07:33:28",
"upload_time_iso_8601": "2023-08-29T07:33:28.622521Z",
"url": "https://files.pythonhosted.org/packages/11/5b/45fff65aaad412c9c54827cb821254c10580683d933f5bff40146aa6a594/garpix_user-3.9.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-08-29 07:33:28",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "garpixcms",
"github_project": "garpix_user",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "garpix-user"
}