Merge branch 'feature/adm_ruleset/backend' into 'develop'

Feature/adm ruleset/backend

See merge request 2020-2021/online/s101/group-02/access_controller!28
This commit is contained in:
Кравченко Артем 2021-03-04 16:20:17 +00:00
commit 3a448a399a
8 changed files with 137 additions and 30 deletions

View File

@ -0,0 +1,17 @@
# Generated by Django 3.1.6 on 2021-03-02 19:55
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('main', '0004_rolechangelogs'),
]
operations = [
migrations.AlterModelOptions(
name='userprofile',
options={'permissions': [('admin', 'Have access to control page')]},
),
]

View File

@ -0,0 +1,16 @@
# Generated by Django 3.1.6 on 2021-03-03 19:32
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('main', '0005_auto_20210302_2255'),
]
operations = [
migrations.DeleteModel(
name='UserProfile',
),
]

View File

@ -0,0 +1,29 @@
# Generated by Django 3.1.6 on 2021-03-03 19:35
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('main', '0006_delete_userprofile'),
]
operations = [
migrations.CreateModel(
name='UserProfile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('role', models.CharField(default='None', max_length=100)),
('image', models.URLField(blank=True, null=True)),
('name', models.CharField(default='None', max_length=100)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'permissions': [('control_access', 'User has access to control page')],
},
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 3.1.6 on 2021-03-03 20:05
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('main', '0007_userprofile'),
]
operations = [
migrations.AlterModelOptions(
name='userprofile',
options={},
),
]

View File

@ -11,6 +11,9 @@
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<div class="btn-group" role="group" aria-label="Basic example"> <div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-secondary" href="{% url 'profile' %}">Профиль</a> <a class="btn btn-secondary" href="{% url 'profile' %}">Профиль</a>
{% if perms.main.has_control_access %}
<a class="btn btn-secondary" href="{% url 'control' %}">Управление</a>
{% endif %}
<a class="btn btn-secondary" href="{% url 'logout' %}">Выйти</a> <a class="btn btn-secondary" href="{% url 'logout' %}">Выйти</a>
</div> </div>
{% else %} {% else %}

View File

@ -2,7 +2,7 @@
{% load static %} {% load static %}
{% block title %}Управление{%endblock %} {% block title %}Управление{% endblock %}
{% block heading %}Управление{% endblock %} {% block heading %}Управление{% endblock %}
@ -16,19 +16,24 @@
<p class="row page-description">Основная информация о странице</p> <p class="row page-description">Основная информация о странице</p>
</div> </div>
{% block form %}
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
<div class="row justify-content-center new-section"> <div class="row justify-content-center new-section">
{% block hidden_form %}
<div style="display: none"> <div style="display: none">
{% for field in form.users %} {% for field in form.users %}
{{ field.tag }} {{ field.tag }}
{% endfor %} {% endfor %}
</div> </div>
{% endblock %}
<div class="col-10"> <div class="col-10">
<h6 class="table-title">Список сотрудников</h6> <h6 class="table-title">Список сотрудников</h6>
{% block table %}
<table class="light-table"> <table class="light-table">
<thead> <thead>
@ -52,10 +57,12 @@
</tbody> </tbody>
</table> </table>
{% endblock%}
</div> </div>
</div> </div>
{% block count %}
<div class="row justify-content-center new-section"> <div class="row justify-content-center new-section">
<div class="col-5"> <div class="col-5">
<div class="info"> <div class="info">
@ -91,19 +98,11 @@
</div> </div>
</div> </div>
{% endblock %}
</form> </form>
{% endblock %}
</div> </div>
<script> <script src="{% static 'main/js/control.js'%}"></script>
"use strict";
let checkboxes = document.getElementsByName("users");
let fields = document.querySelectorAll(".checkbox_field");
if (checkboxes.length == fields.length) {
for (let i = 0; i < fields.length; ++i) {
let el = checkboxes[i].cloneNode(true);
fields[i].appendChild(el);
}
}
</script>
{% endblock %} {% endblock %}

View File

@ -1,26 +1,30 @@
import logging import logging
import os import os
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import PasswordResetForm
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
from django.contrib.auth.tokens import default_token_generator from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth.forms import PasswordResetForm
from django.contrib.auth.views import LoginView from django.contrib.auth.views import LoginView
from django.core.exceptions import PermissionDenied from django.contrib.contenttypes.models import ContentType
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import get_list_or_404, redirect, reverse, render from django.shortcuts import render, get_list_or_404, redirect
from django.urls import reverse_lazy from django.urls import reverse_lazy, reverse
from django.views.generic import FormView from django.views.generic import FormView
from django_registration.views import RegistrationView
from zenpy import Zenpy from zenpy import Zenpy
from zenpy.lib.api_objects import User as ZenpyUser
from access_controller.settings import EMAIL_HOST_USER, ZENDESK_ROLES from access_controller.settings import EMAIL_HOST_USER
from main.extra_func import check_user_exist, update_profile, get_user_organization, make_engineer, make_light_agent, \ from main.extra_func import check_user_exist, update_profile, get_user_organization, \
get_users_list make_engineer, make_light_agent, get_users_list
from main.forms import AdminPageUsers, CustomRegistrationForm, CustomAuthenticationForm
from .models import UserProfile from django.contrib.auth.models import User, Permission
from main.models import UserProfile
from main.forms import CustomRegistrationForm, AdminPageUsers, CustomAuthenticationForm
from django_registration.views import RegistrationView
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.core.exceptions import PermissionDenied
from access_controller.settings import ZENDESK_ROLES
from zenpy.lib.api_objects import User as ZenpyUser
class CustomRegistrationView(RegistrationView): class CustomRegistrationView(RegistrationView):
@ -58,12 +62,27 @@ class CustomRegistrationView(RegistrationView):
) )
forms.save(**opts) forms.save(**opts)
update_profile(user.userprofile) update_profile(user.userprofile)
self.set_permission(user)
return user return user
else: else:
raise ValueError('Непредвиденная ошибка') raise ValueError('Непредвиденная ошибка')
else: else:
self.is_allowed = False self.is_allowed = False
@staticmethod
def set_permission(user) -> None:
"""
Дает разрешение на просмотр страница администратора, если пользователь имеет роль admin
"""
content_type = ContentType.objects.get_for_model(UserProfile)
permission, created = Permission.objects.get_or_create(
codename='has_control_access',
content_type=content_type,
)
if user.userprofile.role == 'admin':
user.user_permissions.add(permission)
def get_success_url(self, user: User = None) -> success_url: def get_success_url(self, user: User = None) -> success_url:
""" """
Возвращает url-адрес страницы, куда нужно перейти после успешной/неуспешной регистрации Возвращает url-адрес страницы, куда нужно перейти после успешной/неуспешной регистрации
@ -148,10 +167,8 @@ def main_page(request):
return render(request, 'pages/index.html') return render(request, 'pages/index.html')
class AdminPageView(FormView, LoginRequiredMixin): class AdminPageView(FormView, LoginRequiredMixin, PermissionRequiredMixin):
""" permission_required = 'main.has_control_access'
Class AdminPageView - логика работы страницы администратора
"""
template_name = 'pages/adm_ruleset.html' template_name = 'pages/adm_ruleset.html'
form_class = AdminPageUsers form_class = AdminPageUsers
success_url = '/control/' success_url = '/control/'

View File

@ -0,0 +1,9 @@
"use strict";
let checkboxes = document.getElementsByName("users");
let fields = document.querySelectorAll(".checkbox_field");
if (checkboxes.length == fields.length) {
for (let i = 0; i < fields.length; ++i) {
let el = checkboxes[i].cloneNode(true);
fields[i].appendChild(el);
}
}