From b8e3d11c6f9d397fd6448a87c97a110bba05ec60 Mon Sep 17 00:00:00 2001 From: Sokurov Idar Date: Mon, 8 Feb 2021 19:10:44 +0300 Subject: [PATCH 1/5] Add first version registration --- access_controller/settings.py | 1 + access_controller/urls.py | 5 ++- .../django_registration_complete.html | 10 +++++ .../registration_form.html | 20 ++++++++++ main/views.py | 39 ++++++++++++++++++- 5 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 main/templates/django_registration/django_registration_complete.html create mode 100644 main/templates/django_registration/registration_form.html diff --git a/access_controller/settings.py b/access_controller/settings.py index dc44189..8f61695 100644 --- a/access_controller/settings.py +++ b/access_controller/settings.py @@ -37,6 +37,7 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'django_registration', 'main', ] diff --git a/access_controller/urls.py b/access_controller/urls.py index e0ecf63..eb189ef 100644 --- a/access_controller/urls.py +++ b/access_controller/urls.py @@ -16,6 +16,9 @@ Including another URLconf from django.contrib import admin from django.urls import path +from main.views import Reg + urlpatterns = [ - path('admin/', admin.site.urls), + path('admin/', admin.site.urls, name='admin'), + path('register/', Reg.as_view(), name='registration'), ] diff --git a/main/templates/django_registration/django_registration_complete.html b/main/templates/django_registration/django_registration_complete.html new file mode 100644 index 0000000..61a69c0 --- /dev/null +++ b/main/templates/django_registration/django_registration_complete.html @@ -0,0 +1,10 @@ + + + + + Title + + +NIce + + diff --git a/main/templates/django_registration/registration_form.html b/main/templates/django_registration/registration_form.html new file mode 100644 index 0000000..6b84e1d --- /dev/null +++ b/main/templates/django_registration/registration_form.html @@ -0,0 +1,20 @@ + + + + + Title + + +

Регистрация

+
+ {% csrf_token %} + {% for field in form %} + {{ field.label_tag }} + {{ field }} +
+ {% if field.errors %}
{{ field.errors }}
{% endif %} +{% endfor %} + + + + diff --git a/main/views.py b/main/views.py index 91ea44a..a6208c4 100644 --- a/main/views.py +++ b/main/views.py @@ -1,3 +1,38 @@ -from django.shortcuts import render - # Create your views here. +from abc import ABC + +from django.contrib.auth.models import User +from django.urls import reverse_lazy +from django_registration.forms import RegistrationFormUniqueEmail +from django_registration.views import RegistrationView +from zenpy import Zenpy + +from main.models import UserProfile + + +class Reg(RegistrationView): + form_class = RegistrationFormUniqueEmail + template_name = 'django_registration/registration_form.html' + + def register(self, form): + creds = { + 'email': 'DEFINEME', + 'subdomain': 'ngenix1612197338', + 'token': 'DEFINEME', + } + client = Zenpy(**creds) + zenpy_user = client.search(form.data['email'], type='user') + if zenpy_user: + user = User.objects.create_user( + username=form.data['username'], + email=form.data['email'], + password=form.data['email'], + ) + profile=UserProfile.objects.create( + image='None.png', + user=user, + role='None' + ) + user.save() + else: + raise AttributeError('No such email') From 729c0bec7ec6f301fea492b16e3035e3ba57c1ff Mon Sep 17 00:00:00 2001 From: Sokurov Idar Date: Mon, 8 Feb 2021 20:12:24 +0300 Subject: [PATCH 2/5] Email on zendesk exist check --- access_controller/urls.py | 8 ++-- main/extra_func.py | 4 +- main/migrations/0002_userprofile_name.py | 18 ++++++++ main/models.py | 1 + .../django_registration_complete.html | 10 ----- .../registration_closed.html | 15 +++++++ .../registration_complete.html | 14 +++++++ .../registration_form.html | 42 ++++++++++--------- main/views.py | 29 +++++++------ requirements.txt | 2 + 10 files changed, 95 insertions(+), 48 deletions(-) create mode 100644 main/migrations/0002_userprofile_name.py delete mode 100644 main/templates/django_registration/django_registration_complete.html create mode 100644 main/templates/django_registration/registration_closed.html create mode 100644 main/templates/django_registration/registration_complete.html diff --git a/access_controller/urls.py b/access_controller/urls.py index b9f7386..9262d42 100644 --- a/access_controller/urls.py +++ b/access_controller/urls.py @@ -15,15 +15,15 @@ Including another URLconf """ from django.conf.urls.static import static from django.contrib import admin -from django.urls import path +from django.urls import path, include from access_controller import settings from main.views import * urlpatterns = [ path('admin/', admin.site.urls, name='admin'), - path('register/', Reg.as_view(), name='registration'), - path('admin/', admin.site.urls), - path('profile/', profile_page, name="Profile"), + path('register/', CustomRegistrationView.as_view(), name='registration'), + path('', include('django_registration.backends.one_step.urls')), + path('profile/', profile_page, name='profile'), ] urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/main/extra_func.py b/main/extra_func.py index 6d74db6..487fb13 100644 --- a/main/extra_func.py +++ b/main/extra_func.py @@ -2,9 +2,9 @@ from main.models import UserProfile # Дополнительные функции -def set_and_get_username(UP: UserProfile): # TODO: Переделать с получением данных через API +def set_and_get_name(UP: UserProfile): # TODO: Переделать с получением данных через API """ - Функция устанавливает поле :class:`user.username` текущим именем в Zendesk + Функция устанавливает поле :class:`username` текущим именем в Zendesk :param UP: Объект профиля пользователя :type UP: :class:`main.models.UserProfile` diff --git a/main/migrations/0002_userprofile_name.py b/main/migrations/0002_userprofile_name.py new file mode 100644 index 0000000..1737da2 --- /dev/null +++ b/main/migrations/0002_userprofile_name.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.6 on 2021-02-08 16:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='userprofile', + name='name', + field=models.CharField(default='None', max_length=100), + ), + ] diff --git a/main/models.py b/main/models.py index 73fb9ce..96d04db 100644 --- a/main/models.py +++ b/main/models.py @@ -8,3 +8,4 @@ class UserProfile(models.Model): user = models.OneToOneField(to=User, on_delete=models.CASCADE) role = models.IntegerField() image = models.ImageField(upload_to='user_avatars') + name = models.CharField(default='None', max_length=100) diff --git a/main/templates/django_registration/django_registration_complete.html b/main/templates/django_registration/django_registration_complete.html deleted file mode 100644 index 61a69c0..0000000 --- a/main/templates/django_registration/django_registration_complete.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - Title - - -NIce - - diff --git a/main/templates/django_registration/registration_closed.html b/main/templates/django_registration/registration_closed.html new file mode 100644 index 0000000..9aa808d --- /dev/null +++ b/main/templates/django_registration/registration_closed.html @@ -0,0 +1,15 @@ +{% extends 'base/base.html' %} +{% load static %} + +{% block title %} + Регистрация завершена +{% endblock %} + +{% block heading %} + Регистрация +{% endblock %} + +{% block content %} +
+

Нет пользователя с указаным адресом электронной почты

+{% endblock %} diff --git a/main/templates/django_registration/registration_complete.html b/main/templates/django_registration/registration_complete.html new file mode 100644 index 0000000..8da81c0 --- /dev/null +++ b/main/templates/django_registration/registration_complete.html @@ -0,0 +1,14 @@ +{% extends 'base/base.html' %} + +{% block title %} + Регистрация завершена +{% endblock %} + +{% block heading %} + Регистрация +{% endblock %} + +{% block content %} +
+

Регистрация прошла успешно. Войти сейчас

+{% endblock %} diff --git a/main/templates/django_registration/registration_form.html b/main/templates/django_registration/registration_form.html index 6b84e1d..c4bb388 100644 --- a/main/templates/django_registration/registration_form.html +++ b/main/templates/django_registration/registration_form.html @@ -1,20 +1,24 @@ - - - - - Title - - -

Регистрация

- - {% csrf_token %} - {% for field in form %} - {{ field.label_tag }} - {{ field }} -
- {% if field.errors %}
{{ field.errors }}
{% endif %} -{% endfor %} +{% extends 'base/base.html' %} +{% load static %} - - - +{% block title %} + Регистрация +{% endblock %} + +{% block heading %} + Регистрация +{% endblock %} +{% block content %} + + {% csrf_token %} + {% for field in form %} + {{ field.label_tag }} + {{ field }} +
+ {% if field.errors %} + {{ field.errors }} + {% endif %} + {% endfor %} + + +{% endblock %} diff --git a/main/views.py b/main/views.py index c8271ee..2de5f8b 100644 --- a/main/views.py +++ b/main/views.py @@ -1,26 +1,25 @@ from django.shortcuts import render, redirect +from django.urls import reverse_lazy -from main.extra_func import set_and_get_username, set_and_get_email, load_and_get_image, set_and_get_role +from main.extra_func import set_and_get_name, set_and_get_email, load_and_get_image, set_and_get_role from main.models import UserProfile from django.contrib.auth.models import User -from django.urls import reverse_lazy from django_registration.forms import RegistrationFormUniqueEmail from django_registration.views import RegistrationView from zenpy import Zenpy -from main.models import UserProfile - -class Reg(RegistrationView): +class CustomRegistrationView(RegistrationView): form_class = RegistrationFormUniqueEmail template_name = 'django_registration/registration_form.html' + success_url = reverse_lazy('django_registration_complete') def register(self, form): creds = { - 'email': 'DEFINEME', + 'email': 'idar.sokurov.05@mail.ru', 'subdomain': 'ngenix1612197338', - 'token': 'DEFINEME', + 'token': 'xRL9Qqz7svFE3X9cHMVC2zOtJUdllzr441C3Z363', } client = Zenpy(**creds) zenpy_user = client.search(form.data['email'], type='user') @@ -28,16 +27,20 @@ class Reg(RegistrationView): user = User.objects.create_user( username=form.data['username'], email=form.data['email'], - password=form.data['email'], + password=form.data['password1'] ) - profile = UserProfile.objects.create( + profile = UserProfile( image='None.png', user=user, - role='None' + role=0, ) - user.save() + set_and_get_name(profile) + set_and_get_email(profile) + set_and_get_role(profile) + load_and_get_image(profile) + profile.save() else: - raise AttributeError('No such email') + self.success_url = reverse_lazy('django_registration_disallowed') def profile_page(request): @@ -53,7 +56,7 @@ def profile_page(request): else: # TODO: Убрать после появления регистрации и авторизации, добавить login_required() UP = UserProfile.objects.get(user=1) context = { - 'name': set_and_get_username(UP), + 'name': set_and_get_name(UP), 'email': set_and_get_email(UP), 'role': set_and_get_role(UP), 'image_name': load_and_get_image(UP), diff --git a/requirements.txt b/requirements.txt index 2f0966d..f51fa7a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,9 @@ # Engine Django==3.1.6 Pillow==8.1.0 +zenpy~=2.0.24 # Documentation Sphinx==3.4.3 sphinx-rtd-theme==0.5.1 + From 0bc34f810090d10097879124af7273216817a18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BE=D0=BA=D1=83=D1=80=D0=BE=D0=B2=20=D0=98=D0=B4?= =?UTF-8?q?=D0=B0=D1=80?= Date: Mon, 8 Feb 2021 17:17:03 +0000 Subject: [PATCH 3/5] Update main/views.py, README.md files --- README.md | 1 + main/views.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4230f3c..f27d6b3 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ pip install -r requirements.txt ./manage.py migrate ./manage.py shell -c "from django.contrib.auth import get_user_model; get_user_model().objects.create_superuser('vasya', '1@abc.net', 'promprog')" ./manage.py runserver +Создать токен и указать вместе с почтой в запросах к Zendesk ``` ## Read more diff --git a/main/views.py b/main/views.py index 2de5f8b..e377db5 100644 --- a/main/views.py +++ b/main/views.py @@ -17,9 +17,9 @@ class CustomRegistrationView(RegistrationView): def register(self, form): creds = { - 'email': 'idar.sokurov.05@mail.ru', + 'email': 'DEFINE ME', 'subdomain': 'ngenix1612197338', - 'token': 'xRL9Qqz7svFE3X9cHMVC2zOtJUdllzr441C3Z363', + 'token': 'DEFINE ME', } client = Zenpy(**creds) zenpy_user = client.search(form.data['email'], type='user') From 938b9894fe12e98ea6fd10aba0cea4f60533c059 Mon Sep 17 00:00:00 2001 From: Sokurov Idar Date: Wed, 10 Feb 2021 19:05:46 +0300 Subject: [PATCH 4/5] Add Zendesk password check Add Bootstrap to forms Add custom form --- main/extra_func.py | 55 +++++++++++++++++++ main/forms.py | 34 ++++++++++++ .../registration_closed.html | 2 +- .../registration_complete.html | 2 +- main/views.py | 35 +++++++----- 5 files changed, 112 insertions(+), 16 deletions(-) create mode 100644 main/forms.py diff --git a/main/extra_func.py b/main/extra_func.py index 487fb13..8f850b8 100644 --- a/main/extra_func.py +++ b/main/extra_func.py @@ -1,3 +1,8 @@ +import os + +from zenpy import Zenpy +from zenpy.lib.exception import APIException + from main.models import UserProfile @@ -9,6 +14,7 @@ def set_and_get_name(UP: UserProfile): # TODO: Переделать с полу :param UP: Объект профиля пользователя :type UP: :class:`main.models.UserProfile` :return: Имя пользователя + :rtype: :class:`str` """ return UP.user.username @@ -20,6 +26,7 @@ def set_and_get_email(UP: UserProfile): # TODO: Переделать с пол :param UP: Объект профиля пользователя :type UP: :class:`main.models.UserProfile` :return: Почта пользователя + :rtype: :class:`str` """ return UP.user.email @@ -31,6 +38,7 @@ def set_and_get_role(UP: UserProfile): # TODO: Переделать с полу :param UP: Объект профиля пользователя :type UP: :class:`main.models.UserProfile` :return: Роль пользователя + :rtype: :class:`str` """ return UP.role @@ -42,5 +50,52 @@ def load_and_get_image(UP: UserProfile): # TODO: Переделать с пол :param UP: Объект профиля пользователя :type UP: :class:`main.models.UserProfile` :return: Название изображения + :rtype: :class:`str` """ return UP.image.name + + +def check_user_exist(email: str) -> bool: + """ + Функция проверяет, существует ли пользователь + + :param email: Электронная почта пользователя + :type email: :class:`str + :return: True, если существует, иначе False + :rtype: :class:`bool' + """ + admin_creds = { + 'email': os.environ.get('Admin_email'), + 'subdomain': 'ngenix1612197338', + 'token': os.environ.get('Oauth_token'), + } + admin = Zenpy(**admin_creds) + zenpy_user = admin.search(email, type='user') + if zenpy_user: + return True + return False + + +def check_user_auth(email: str, password: str) -> bool: + """ + Функция проверяет, верны ли входные данные + + :param email: Электроная почта пользователя + :type email: :class:`str` + :param password: Пароль пользователя + :type password: :class:`str` + :return: True, если входные данные верны, иначе False + :raise APIException: исключение, вызываемое если пользователь не аутентифицирован + :rtype: :class:`bool` + """ + try: + creds = { + 'email': email, + 'subdomain': 'ngenix1612197338', + 'password': password, + } + user = Zenpy(**creds) + user.search(email, type='user') + except APIException: + return False + return True diff --git a/main/forms.py b/main/forms.py new file mode 100644 index 0000000..fcd8a7f --- /dev/null +++ b/main/forms.py @@ -0,0 +1,34 @@ +from django import forms +from django_registration.forms import RegistrationFormUniqueEmail + + +class CustomRegistrationForm(RegistrationFormUniqueEmail): + """ + Форма для регистрации :class:`django_registration.forms.RegistrationFormUniqueEmail` + с полем для ввода пароля от Zendesk аккаунта и с добавлением bootstrap-класса 'form-control' для всех полей + + :param password_zen: Поле для ввода пароля от Zendesk + :type password_zen: :class:`django.forms.CharField` + """ + password_zen = forms.CharField( + required=True, + label="Пароль от Zendesk аккаунта", + strip=False, + widget=forms.PasswordInput(attrs={ + 'class': 'form-control' + }) + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + for visible in self.visible_fields(): + if visible.field.widget.attrs.get('class', False): + print(visible.field.widget.attrs['class'].find('form-control')) + if visible.field.widget.attrs['class'].find('form-control') < 0: + visible.field.widget.attrs['class'] += 'form-control' + else: + visible.field.widget.attrs['class'] = 'form-control' + + class Meta(RegistrationFormUniqueEmail.Meta): + fields = RegistrationFormUniqueEmail.Meta.fields + fields.insert(2, 'password_zen') diff --git a/main/templates/django_registration/registration_closed.html b/main/templates/django_registration/registration_closed.html index 9aa808d..4fffce6 100644 --- a/main/templates/django_registration/registration_closed.html +++ b/main/templates/django_registration/registration_closed.html @@ -11,5 +11,5 @@ {% block content %}
-

Нет пользователя с указаным адресом электронной почты

+

Нет пользователя с указаным адресом электронной почты, либо был введён неверный пароль

{% endblock %} diff --git a/main/templates/django_registration/registration_complete.html b/main/templates/django_registration/registration_complete.html index 8da81c0..bb064bb 100644 --- a/main/templates/django_registration/registration_complete.html +++ b/main/templates/django_registration/registration_complete.html @@ -10,5 +10,5 @@ {% block content %}
-

Регистрация прошла успешно. Войти сейчас

+

Регистрация прошла успешно. Войти сейчас

{% endblock %} diff --git a/main/views.py b/main/views.py index 2de5f8b..c02dd4d 100644 --- a/main/views.py +++ b/main/views.py @@ -1,29 +1,26 @@ -from django.shortcuts import render, redirect +from django.shortcuts import render from django.urls import reverse_lazy -from main.extra_func import set_and_get_name, set_and_get_email, load_and_get_image, set_and_get_role +from main.extra_func import set_and_get_name, set_and_get_email, load_and_get_image, set_and_get_role, check_user_exist, \ + check_user_auth from main.models import UserProfile from django.contrib.auth.models import User -from django_registration.forms import RegistrationFormUniqueEmail +from main.forms import CustomRegistrationForm from django_registration.views import RegistrationView -from zenpy import Zenpy class CustomRegistrationView(RegistrationView): - form_class = RegistrationFormUniqueEmail + """ + Отображение и логика работы страницы регистрации пользователя + """ + form_class = CustomRegistrationForm template_name = 'django_registration/registration_form.html' success_url = reverse_lazy('django_registration_complete') + is_allowed = True def register(self, form): - creds = { - 'email': 'idar.sokurov.05@mail.ru', - 'subdomain': 'ngenix1612197338', - 'token': 'xRL9Qqz7svFE3X9cHMVC2zOtJUdllzr441C3Z363', - } - client = Zenpy(**creds) - zenpy_user = client.search(form.data['email'], type='user') - if zenpy_user: + if check_user_exist(form.data['email']) and check_user_auth(form.data['email'], form.data['password_zen']): user = User.objects.create_user( username=form.data['username'], email=form.data['email'], @@ -40,7 +37,17 @@ class CustomRegistrationView(RegistrationView): load_and_get_image(profile) profile.save() else: - self.success_url = reverse_lazy('django_registration_disallowed') + self.is_allowed = False + + def get_success_url(self, request): + """ + Вовзращет url-адресс страницы, куда нужно перейти после успешной/неуспешной регистрации + Используется самой django-registration + """ + if self.is_allowed: + return reverse_lazy('django_registration_complete') + else: + return reverse_lazy('django_registration_disallowed') def profile_page(request): From 8de78e06c44bdba96e052701bb95baa363238acd Mon Sep 17 00:00:00 2001 From: Sokurov Idar Date: Wed, 10 Feb 2021 19:16:27 +0300 Subject: [PATCH 5/5] Merge branch 'feature/registration' --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f27d6b3..db34259 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,10 @@ pip install -r requirements.txt ./manage.py migrate ./manage.py shell -c "from django.contrib.auth import get_user_model; get_user_model().objects.create_superuser('vasya', '1@abc.net', 'promprog')" ./manage.py runserver -Создать токен и указать вместе с почтой в запросах к Zendesk ``` +Создать токен + +Указать почту и токен в окружении ## Read more - Zenpy: [http://docs.facetoe.com.au](http://docs.facetoe.com.au)