Merge branch 'feature/registration' into 'develop'

Feature/registration

See merge request 2020-2021/online/s101/group-02/access_controller!3
This commit is contained in:
Кравченко Артем 2021-02-10 19:38:42 +00:00
commit b2fdd42f45
12 changed files with 223 additions and 9 deletions

View File

@ -47,6 +47,9 @@ pip install -r requirements.txt
./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 shell -c "from django.contrib.auth import get_user_model; get_user_model().objects.create_superuser('vasya', '1@abc.net', 'promprog')"
./manage.py runserver ./manage.py runserver
``` ```
Создать токен
Указать почту и токен в окружении
## Read more ## Read more
- Zenpy: [http://docs.facetoe.com.au](http://docs.facetoe.com.au) - Zenpy: [http://docs.facetoe.com.au](http://docs.facetoe.com.au)

View File

@ -35,6 +35,7 @@ INSTALLED_APPS = [
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'django_registration',
'main', 'main',
] ]

View File

@ -15,13 +15,15 @@ Including another URLconf
""" """
from django.conf.urls.static import static from django.conf.urls.static import static
from django.contrib import admin from django.contrib import admin
from django.urls import path from django.urls import path, include
from access_controller import settings from access_controller import settings
from main.views import * from main.views import *
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls, name='admin'),
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) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -1,14 +1,20 @@
import os
from zenpy import Zenpy
from zenpy.lib.exception import APIException
from main.models import UserProfile 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: Объект профиля пользователя :param UP: Объект профиля пользователя
:type UP: :class:`main.models.UserProfile` :type UP: :class:`main.models.UserProfile`
:return: Имя пользователя :return: Имя пользователя
:rtype: :class:`str`
""" """
return UP.user.username return UP.user.username
@ -20,6 +26,7 @@ def set_and_get_email(UP: UserProfile): # TODO: Переделать с пол
:param UP: Объект профиля пользователя :param UP: Объект профиля пользователя
:type UP: :class:`main.models.UserProfile` :type UP: :class:`main.models.UserProfile`
:return: Почта пользователя :return: Почта пользователя
:rtype: :class:`str`
""" """
return UP.user.email return UP.user.email
@ -31,6 +38,7 @@ def set_and_get_role(UP: UserProfile): # TODO: Переделать с полу
:param UP: Объект профиля пользователя :param UP: Объект профиля пользователя
:type UP: :class:`main.models.UserProfile` :type UP: :class:`main.models.UserProfile`
:return: Роль пользователя :return: Роль пользователя
:rtype: :class:`str`
""" """
return UP.role return UP.role
@ -42,5 +50,52 @@ def load_and_get_image(UP: UserProfile): # TODO: Переделать с пол
:param UP: Объект профиля пользователя :param UP: Объект профиля пользователя
:type UP: :class:`main.models.UserProfile` :type UP: :class:`main.models.UserProfile`
:return: Название изображения :return: Название изображения
:rtype: :class:`str`
""" """
return UP.image.name 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

34
main/forms.py Normal file
View File

@ -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')

View File

@ -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),
),
]

View File

@ -8,3 +8,4 @@ class UserProfile(models.Model):
user = models.OneToOneField(to=User, on_delete=models.CASCADE) user = models.OneToOneField(to=User, on_delete=models.CASCADE)
role = models.IntegerField() role = models.IntegerField()
image = models.ImageField(upload_to='user_avatars') image = models.ImageField(upload_to='user_avatars')
name = models.CharField(default='None', max_length=100)

View File

@ -0,0 +1,15 @@
{% extends 'base/base.html' %}
{% load static %}
{% block title %}
Регистрация завершена
{% endblock %}
{% block heading %}
Регистрация
{% endblock %}
{% block content %}
<br>
<h4> Нет пользователя с указаным адресом электронной почты, либо был введён неверный пароль</h4>
{% endblock %}

View File

@ -0,0 +1,14 @@
{% extends 'base/base.html' %}
{% block title %}
Регистрация завершена
{% endblock %}
{% block heading %}
Регистрация
{% endblock %}
{% block content %}
<br>
<h4> Регистрация прошла успешно. <a href="/login/">Войти сейчас</a></h4>
{% endblock %}

View File

@ -0,0 +1,24 @@
{% extends 'base/base.html' %}
{% load static %}
{% block title %}
Регистрация
{% endblock %}
{% block heading %}
Регистрация
{% endblock %}
{% block content %}
<form method="post" action="">
{% csrf_token %}
{% for field in form %}
{{ field.label_tag }}
{{ field }}
<br>
{% if field.errors %}
<span>{{ field.errors }}</span>
{% endif %}
{% endfor %}
<input type="submit" value="Зарегистрироваться" class="clearfix">
</form>
{% endblock %}

View File

@ -1,10 +1,55 @@
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_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, check_user_exist, \
check_user_auth
from main.models import UserProfile from main.models import UserProfile
from django.contrib.auth.models import User
from main.forms import CustomRegistrationForm
from django_registration.views import RegistrationView
from zenpy import Zenpy
class CustomRegistrationView(RegistrationView):
"""
Отображение и логика работы страницы регистрации пользователя
"""
form_class = CustomRegistrationForm
template_name = 'django_registration/registration_form.html'
success_url = reverse_lazy('django_registration_complete')
is_allowed = True
def register(self, form):
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'],
password=form.data['password1']
)
profile = UserProfile(
image='None.png',
user=user,
role=0,
)
set_and_get_name(profile)
set_and_get_email(profile)
set_and_get_role(profile)
load_and_get_image(profile)
profile.save()
else:
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')
# Create your views here.
def profile_page(request): def profile_page(request):
""" """
@ -19,7 +64,7 @@ def profile_page(request):
else: # TODO: Убрать после появления регистрации и авторизации, добавить login_required() else: # TODO: Убрать после появления регистрации и авторизации, добавить login_required()
UP = UserProfile.objects.get(user=1) UP = UserProfile.objects.get(user=1)
context = { context = {
'name': set_and_get_username(UP), 'name': set_and_get_name(UP),
'email': set_and_get_email(UP), 'email': set_and_get_email(UP),
'role': set_and_get_role(UP), 'role': set_and_get_role(UP),
'image_name': load_and_get_image(UP), 'image_name': load_and_get_image(UP),

View File

@ -1,7 +1,9 @@
# Engine # Engine
Django==3.1.6 Django==3.1.6
Pillow==8.1.0 Pillow==8.1.0
zenpy~=2.0.24
# Documentation # Documentation
Sphinx==3.4.3 Sphinx==3.4.3
sphinx-rtd-theme==0.5.1 sphinx-rtd-theme==0.5.1