2021-03-21 19:47:42 +03:00

272 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import logging
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import PasswordResetForm
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.contrib.auth.models import User, Permission
from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth.views import LoginView
from django.contrib.contenttypes.models import ContentType
from django.contrib.messages.views import SuccessMessageMixin
from django.core.exceptions import PermissionDenied
from django.core.handlers.wsgi import WSGIRequest
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render, get_list_or_404, redirect
from django.urls import reverse_lazy, reverse
from django.views.generic import FormView
from django_registration.views import RegistrationView
from django.contrib import messages
# Django REST
from rest_framework import viewsets
from rest_framework.response import Response
from zenpy.lib.api_objects import User as ZenpyUser
from access_controller.settings import EMAIL_HOST_USER, ZENDESK_ROLES, ZENDESK_MAX_AGENTS
from main.extra_func import ZendeskAdmin
from main.extra_func import check_user_exist, update_profile, get_user_organization, \
make_engineer, make_light_agent, get_users_list, update_users_in_model, count_users, \
StatisticData
from main.forms import AdminPageUsers, CustomRegistrationForm, CustomAuthenticationForm, StatisticForm
from main.serializers import ProfileSerializer
from .models import UserProfile
class CustomRegistrationView(RegistrationView):
"""
Отображение и логика работы страницы регистрации пользователя
1. Ввод email пользователя, указанный на Zendesk
2. В случае если пользователь с данным паролем зарегистрирован на Zendesk и относится к определенной организации, происходит сброс ссылки с установлением пароля на указанный email
3. Создается пользователь class User, а также его профиль
"""
form_class = CustomRegistrationForm
template_name = 'django_registration/registration_form.html'
success_url = reverse_lazy('django_registration_complete')
is_allowed = True
def register(self, form: CustomRegistrationForm) -> User:
self.is_allowed = True
if check_user_exist(form.data['email']) and get_user_organization(form.data['email']) == 'SYSTEM':
forms = PasswordResetForm(self.request.POST)
if forms.is_valid():
opts = {
'use_https': self.request.is_secure(),
'token_generator': default_token_generator,
'from_email': EMAIL_HOST_USER,
'email_template_name': 'registration/password_reset_email.html',
'subject_template_name': 'registration/password_reset_subject.txt',
'request': self.request,
'html_email_template_name': None,
'extra_email_context': None,
}
user = User.objects.create_user(
username=form.data['email'],
email=form.data['email'],
password=User.objects.make_random_password(length=50)
)
forms.save(**opts)
update_profile(user.userprofile)
self.set_permission(user)
return user
else:
raise ValueError('Непредвиденная ошибка')
else:
self.is_allowed = False
@staticmethod
def set_permission(user) -> None:
"""
Дает разрешение на просмотр страница администратора, если пользователь имеет роль admin
"""
if user.userprofile.role == 'admin':
content_type = ContentType.objects.get_for_model(UserProfile)
permission = Permission.objects.get(
codename='has_control_access',
content_type=content_type,
)
user.user_permissions.add(permission)
def get_success_url(self, user: User = None) -> success_url:
"""
Возвращает url-адрес страницы, куда нужно перейти после успешной/неуспешной регистрации
Используется самой django-registration
"""
if self.is_allowed:
return reverse_lazy('password_reset_done')
else:
return reverse_lazy('django_registration_disallowed')
@login_required()
def profile_page(request: WSGIRequest) -> HttpResponse:
"""
Отображение страницы профиля
"""
user_profile: UserProfile = request.user.userprofile
update_profile(user_profile)
context = {
'profile': user_profile,
'pagename': 'Страница профиля'
}
return render(request, 'pages/profile.html', context)
def auth_user(request):
admin = ZendeskAdmin().admin
zenpy_user: ZenpyUser = admin.users.search(request.user.email).values[0]
return zenpy_user, admin
@login_required()
def work_page(request, id):
users = get_users_list()
if request.user.id == id:
engineers = []
light_agents = []
for user in users:
if user.custom_role_id == ZENDESK_ROLES['engineer']:
engineers.append(user)
elif user.custom_role_id == ZENDESK_ROLES['light_agent']:
light_agents.append(user)
context = {
'engineers': engineers,
'agents': light_agents,
'messages': messages.get_messages(request),
'licences_remaining': max(0, ZENDESK_MAX_AGENTS - len(engineers)),
'pagename': 'Управление правами'
}
return render(request, 'pages/work.html', context)
return redirect("login")
def user_update(zenpy_user, admin, request):
admin.users.update(zenpy_user)
request.user.userprofile.role = "agent"
request.user.userprofile.save()
messages.success(request, "Права были изменены")
@login_required()
def work_hand_over(request):
zenpy_user, admin = auth_user(request)
if zenpy_user.custom_role_id == ZENDESK_ROLES['engineer']:
zenpy_user.custom_role_id = ZENDESK_ROLES['light_agent']
user_update(zenpy_user, admin, request)
return HttpResponseRedirect(reverse('work', args=(request.user.id,)))
@login_required()
def work_become_engineer(request):
zenpy_user, admin = auth_user(request)
if zenpy_user.custom_role_id == ZENDESK_ROLES['light_agent']:
zenpy_user.custom_role_id = ZENDESK_ROLES['engineer']
user_update(zenpy_user, admin, request)
return HttpResponseRedirect(reverse('work', args=(request.user.id,)))
def main_page(request):
"""
Отображение логгирования на главной странице
"""
logger = logging.getLogger('main.index')
logger.info('Index page opened')
return render(request, 'pages/index.html')
class AdminPageView(LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageMixin, FormView):
permission_required = 'main.has_control_access'
template_name = 'pages/adm_ruleset.html'
form_class = AdminPageUsers
success_url = '/control/'
success_message = "Права были изменены."
def form_valid(self, form: AdminPageUsers) -> AdminPageUsers:
"""
Функция установки ролей пользователям
"""
users = form.cleaned_data['users']
if 'engineer' in self.request.POST:
self.make_engineers(users)
elif 'light_agent' in self.request.POST:
self.make_light_agents(users)
return super().form_valid(form)
def make_engineers(self, users):
for user in users:
make_engineer(user, self.request.user)
def make_light_agents(self, users):
for user in users:
make_light_agent(user, self.request.user)
def get_context_data(self, **kwargs) -> dict:
"""
Функция формирования контента страницы администратора (с проверкой прав доступа)
"""
context = super().get_context_data(**kwargs)
users = get_list_or_404(
UserProfile, role='agent')
context['users'] = users
context['engineers'], context['light_agents'] = count_users(get_users_list())
context['licences_remaining'] = max(0, ZENDESK_MAX_AGENTS - context['engineers'])
return context # TODO: need to get profile page url
class CustomLoginView(LoginView):
"""
Отображение страницы авторизации пользователя
"""
form_class = CustomAuthenticationForm
class UsersViewSet(viewsets.ReadOnlyModelViewSet):
"""
Класс для получения пользователей с помощью api
"""
queryset = UserProfile.objects.filter(role='agent')
serializer_class = ProfileSerializer
def list(self, request, *args, **kwargs):
users = update_users_in_model().values
count = count_users(users)
profiles = UserProfile.objects.filter(role='agent')
serializer = self.get_serializer(profiles, many=True)
return Response({
'users': serializer.data,
'engineers': count[0],
'light_agents': count[1]
})
@login_required()
def statistic_page(request):
if not request.user.has_perm('main.has_control_access'):
raise PermissionDenied
context = {
'pagename': 'страница статистики',
'errors': list(),
}
if request.method == "POST":
form = StatisticForm(request.POST)
if form.is_valid():
start_date, end_date = form.cleaned_data['range_start'], form.cleaned_data['range_end']
interval, show = form.cleaned_data['interval'], form.cleaned_data['display_format']
Data = StatisticData(start_date, end_date, form.cleaned_data['email'])
Data.set_display(show)
Data.set_interval(interval)
stats = Data.get_statistic()
if Data.errors:
context['errors'] = Data.errors
if Data.warnings:
context['warnings'] = Data.warnings
context['log_stats'] = stats if not context['errors'] else None
if request.method == 'GET':
form = StatisticForm()
context['form'] = form
return render(request, 'pages/stat.html', context)