merge ad- and mail-groups into one

This commit is contained in:
Andreas Zweili 2022-03-30 23:52:44 +02:00
parent 388b9bbadb
commit cda6fc53fd
17 changed files with 80 additions and 356 deletions

View File

@ -3,12 +3,10 @@ from django.contrib import admin
from licenses.models import LicenseWithUser
from .models import (
AdGroup,
Group,
MailAlias,
MailGroup,
User,
UserInAdGroup,
UserInMailGroup,
UserInGroup,
)
@ -18,18 +16,12 @@ class LicenseWithUserInLine(admin.StackedInline):
verbose_name_plural = "Licenses"
class AdGroupInLine(admin.StackedInline):
model = UserInAdGroup
class GroupInLine(admin.StackedInline):
model = UserInGroup
extra = 0
verbose_name_plural = "AD Groups"
class MailGroupInLine(admin.StackedInline):
model = UserInMailGroup
extra = 0
verbose_name_plural = "Mail Groups"
class MailAliasInLine(admin.StackedInline):
model = MailAlias
extra = 0
@ -39,16 +31,13 @@ class MailAliasInLine(admin.StackedInline):
class UserAdmin(admin.ModelAdmin):
list_display = ("name", "customer", "enabled")
inlines = (
AdGroupInLine,
MailGroupInLine,
GroupInLine,
MailAliasInLine,
LicenseWithUserInLine,
)
admin.site.register(AdGroup)
admin.site.register(Group)
admin.site.register(MailAlias)
admin.site.register(MailGroup)
admin.site.register(User, UserAdmin)
admin.site.register(UserInAdGroup)
admin.site.register(UserInMailGroup)
admin.site.register(UserInGroup)

View File

@ -1,3 +1,3 @@
from .user import User, UserInAdGroup, UserInMailGroup
from .groups import AdGroup, Group, MailGroup
from .user import User, UserInGroup
from .groups import Group
from .mailalias import MailAlias

View File

@ -1,42 +1,17 @@
from django.db import models
from model_utils.managers import InheritanceManager
from customers.models import Customer
class Group(models.Model):
name = models.CharField(max_length=50)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
objects = InheritanceManager()
class Meta:
abstract = True
mail_address = models.EmailField()
def __str__(self):
return self.name
class AdGroup(Group):
class Meta:
ordering = ["name"]
verbose_name_plural = "AD Groups"
def get_absolute_url(self):
from django.urls import reverse
return reverse("ad_group", args=[str(self.id)])
class MailGroup(Group):
mail_address = models.EmailField()
class Meta:
ordering = ["name"]
verbose_name_plural = "Mail Groups"
def get_absolute_url(self):
from django.urls import reverse
return reverse("mail_group", args=[str(self.id)])
return reverse("group", args=[str(self.id)])

View File

@ -1,6 +1,6 @@
from django.db import models
from customers.models import Customer
from .groups import AdGroup, MailGroup
from .groups import Group
class User(models.Model):
@ -13,8 +13,7 @@ class User(models.Model):
enabled = models.BooleanField()
description = models.TextField(blank=True)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
ad_groups = models.ManyToManyField(AdGroup, through="UserInAdGroup")
mail_groups = models.ManyToManyField(MailGroup, through="UserInMailGroup")
groups = models.ManyToManyField(Group, through="UserInGroup")
class Meta:
ordering = ["name"]
@ -28,11 +27,6 @@ class User(models.Model):
return reverse("user", args=[str(self.id)])
class UserInAdGroup(models.Model):
class UserInGroup(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
group = models.ForeignKey(AdGroup, on_delete=models.CASCADE)
class UserInMailGroup(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
group = models.ForeignKey(MailGroup, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)

View File

@ -3,8 +3,7 @@ from django_tables2.utils import A
from core.tables import CoreTable
from .models import AdGroup
from .models import MailGroup
from .models import Group
from .models import User
@ -15,8 +14,7 @@ class UsersTable(CoreTable):
attrs={"td": {"class": "text-truncate", "style": "max-width: 150px;"}}
)
customer = tables.Column("Customer", linkify=True)
ad_groups = tables.ManyToManyColumn()
mail_groups = tables.ManyToManyColumn()
groups = tables.ManyToManyColumn()
delete = tables.LinkColumn(
"user_delete",
text="delete",
@ -33,12 +31,12 @@ class UsersTable(CoreTable):
model = User
class AdGroupsTable(CoreTable):
class GroupsTable(CoreTable):
id = tables.Column(visible=False)
name = tables.Column("Ad Groups", linkify=True)
name = tables.Column("Groups", linkify=True)
customer = tables.Column(visible=False)
action = tables.LinkColumn(
"ad_group_delete",
"group_delete",
text="delete",
args=[A("pk")],
attrs={
@ -50,25 +48,4 @@ class AdGroupsTable(CoreTable):
)
class Meta(CoreTable.Meta):
model = AdGroup
class MailGroupsTable(CoreTable):
id = tables.Column(visible=False)
name = tables.Column("Mail Groups", linkify=True)
mail_address = tables.EmailColumn(verbose_name="Mail Address")
customer = tables.Column(visible=False)
action = tables.LinkColumn(
"mail_group_delete",
text="delete",
args=[A("pk")],
attrs={
"a": {
"class": "delete material-icons",
}
},
orderable=False,
)
class Meta(CoreTable.Meta):
model = MailGroup
model = Group

View File

@ -1,11 +1,11 @@
{% extends "core/base.html" %}
{% block section_title %}Delete AD group{% endblock %}
{% block section_title %}Delete Group{% endblock %}
{% block content %}
<div class="row">
<form method="post">{% csrf_token %}
<p>Are you sure you want to delete the AD group "{{ object }}"?</p>
<p>Are you sure you want to delete the group "{{ object }}"?</p>
<button type="submit" class="btn btn-danger">Delete</button>
<a href="{% url 'ad_groups' object.customer.pk %}" class="btn btn-primary">Cancel</a>
<a href="{% url 'groups' object.customer.pk %}" class="btn btn-primary">Cancel</a>
<input type="hidden" id="previous_page" name="previous_page" value="/previous/page/url">
</form>
<script>

View File

@ -3,10 +3,6 @@
{% block section_title %}{{ customer }} Groups{% endblock %}
{% block content %}
<div class="table-responsive">
{% render_table ad_groups %}
</div>
<div class="table-responsive">
{% render_table mail_groups %}
{% render_table groups %}
</div>
{% endblock %}

View File

@ -1,16 +0,0 @@
{% extends "core/base.html" %}
{% block section_title %}Delete Mail group{% endblock %}
{% block content %}
<div class="row">
<form method="post">{% csrf_token %}
<p>Are you sure you want to delete the mail group "{{ object }}"?</p>
<button type="submit" class="btn btn-danger">Delete</button>
<a href="{% url 'mail_groups' object.customer.pk %}" class="btn btn-primary">Cancel</a>
<input type="hidden" id="previous_page" name="previous_page" value="/previous/page/url">
</form>
<script>
prev = document.getElementById("previous_page");
prev.value = document.referrer;
</script>
</div>
{% endblock %}

View File

@ -45,7 +45,7 @@
</div>
</div>
{% if ad_groups or mail_groups or mail_alias %}
{% if groups or mail_alias %}
<div class="col">
{% if mail_alias %}
<div class="card mt-3">
@ -64,31 +64,15 @@
</div>
{% endif %}
{% if ad_groups %}
<div class="card mt-3">
<div class="card-header">AD Groups</div>
<div class="card-body">
<table class="table table-bordered">
{% for group in ad_groups %}
<tr>
<td>{{ group.group }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
{% endif %}
{% if mail_groups %}
<div class="card mt-3">
<div class="card-header">Mail Groups</div>
{% if groups %} <div class="card mt-3">
<div class="card-header">Groups</div>
<div class="card-body">
<table class="table table-bordered">
<tr>
<th>Group Name</th>
<th>Address</th>
</tr>
{% for group in mail_groups %}
{% for group in groups %}
<tr>
<td>{{ group.group }}</td>
<td>{{ group.group.mail_address }}</td>

View File

@ -9,24 +9,22 @@ from customers.models import Customer
pytestmark = pytest.mark.django_db
def test_customer_ad_group_table_not_logged_in():
def test_customer_group_table_not_logged_in():
response = Client().get("/customer/1/groups/")
assert response.status_code == 302 and "login" in response.url
def test_customer_ad_group_table(create_admin_user):
def test_customer_group_table(create_admin_user):
fixture = create_admin_user()
customer = fixture["customer"]
client = Client()
client.login(username="pharma-admin", password="password")
ad_group = mixer.blend("users.AdGroup", customer=customer)
group = mixer.blend("users.Group", customer=customer)
response = client.get("/customer/" + str(customer.id) + "/groups/")
assert response.status_code == 200 and helper.in_content(
response, ad_group
)
assert response.status_code == 200 and helper.in_content(response, group)
def test_customer_ad_group_table_no_group(create_admin_user):
def test_customer_group_table_no_group(create_admin_user):
fixture = create_admin_user()
customer = fixture["customer"]
client = Client()
@ -35,23 +33,23 @@ def test_customer_ad_group_table_no_group(create_admin_user):
assert response.status_code == 200
def test_customer_ad_group_table_no_permission(create_admin_user):
def test_customer_group_table_no_permission(create_admin_user):
create_admin_user()
customer = Customer.objects.create(name="Water Corp.")
client = Client()
client.login(username="pharma-admin", password="password")
mixer.blend("users.AdGroup", customer=customer)
mixer.blend("users.Group", customer=customer)
response = client.get("/customer/" + str(customer.id) + "/groups/")
assert response.status_code == 403
def test_customer_ad_group_table_multiple_groups(create_admin_user):
def test_customer_group_table_multiple_groups(create_admin_user):
fixture = create_admin_user()
customer = fixture["customer"]
client = Client()
client.login(username="pharma-admin", password="password")
group1 = mixer.blend("users.AdGroup", customer=mixer.SELECT)
group2 = mixer.blend("users.AdGroup", customer=mixer.SELECT)
group1 = mixer.blend("users.Group", customer=mixer.SELECT)
group2 = mixer.blend("users.Group", customer=mixer.SELECT)
response = client.get("/customer/" + str(customer.id) + "/groups/")
assert (
response.status_code == 200

View File

@ -1,60 +0,0 @@
import pytest
from django.test import Client
from mixer.backend.django import mixer
from core.tests import helper
from customers.models import Customer
pytestmark = pytest.mark.django_db
def test_customer_mail_group_table_not_logged_in():
response = Client().get("/customer/1/groups/")
assert response.status_code == 302 and "login" in response.url
def test_customer_mail_group_table(create_admin_user):
fixture = create_admin_user()
customer = fixture["customer"]
client = Client()
client.login(username="pharma-admin", password="password")
mail_group = mixer.blend("users.MailGroup", customer=customer)
response = client.get("/customer/" + str(customer.id) + "/groups/")
assert response.status_code == 200 and helper.in_content(
response, mail_group
)
def test_customer_mail_group_table_no_group(create_admin_user):
fixture = create_admin_user()
customer = fixture["customer"]
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/customer/" + str(customer.id) + "/groups/")
assert response.status_code == 200
def test_customer_mail_group_table_no_permission(create_admin_user):
create_admin_user()
customer = Customer.objects.create(name="Water Corp.")
client = Client()
client.login(username="pharma-admin", password="password")
mixer.blend("users.MailGroup", customer=customer)
response = client.get("/customer/" + str(customer.id) + "/groups/")
assert response.status_code == 403
def test_customer_mail_group_table_multiple_groups(create_admin_user):
fixture = create_admin_user()
customer = fixture["customer"]
client = Client()
client.login(username="pharma-admin", password="password")
group1 = mixer.blend("users.MailGroup", customer=mixer.SELECT)
group2 = mixer.blend("users.MailGroup", customer=mixer.SELECT)
response = client.get("/customer/" + str(customer.id) + "/groups/")
assert (
response.status_code == 200
and helper.in_content(response, group1.name)
and helper.in_content(response, group2.name)
)

View File

@ -20,16 +20,13 @@ def test_customer_user_table(create_admin_user):
client = Client()
client.login(username="pharma-admin", password="password")
user = mixer.blend("users.User", customer=mixer.SELECT)
ad_group = mixer.blend("users.AdGroup")
mail_group = mixer.blend("users.MailGroup")
mixer.blend("users.UserInAdGroup", user=user, group=ad_group)
mixer.blend("users.UserInMailGroup", user=user, group=mail_group)
group = mixer.blend("users.Group")
mixer.blend("users.UserInGroup", user=user, group=group)
response = client.get("/customer/" + str(customer.id) + "/users/")
assert (
response.status_code == 200
and helper.in_content(response, user.name)
and helper.in_content(response, ad_group)
and helper.in_content(response, mail_group)
and helper.in_content(response, group)
and helper.in_content(response, user.primary_mail)
)

View File

@ -8,45 +8,45 @@ from core.tests import helper
pytestmark = pytest.mark.django_db
def test_ad_group_detail_view_not_logged_in():
response = Client().get("/ad-group/1/")
def test_group_detail_view_not_logged_in():
response = Client().get("/group/1/")
assert response.status_code == 302 and "login" in response.url
def test_ad_group_detail_view(create_admin_user):
def test_group_detail_view(create_admin_user):
create_admin_user()
group = mixer.blend("users.AdGroup", customer=mixer.SELECT)
group = mixer.blend("users.Group", customer=mixer.SELECT)
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/ad-group/" + str(group.id) + "/")
response = client.get("/group/" + str(group.id) + "/")
assert response.status_code == 200 and helper.in_content(response, group)
def test_ad_group_detail_view_not_found(create_admin_user):
def test_group_detail_view_not_found(create_admin_user):
create_admin_user()
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/ad-group/230/")
response = client.get("/group/230/")
assert response.status_code == 404
def test_ad_group_detail_view_no_permission(create_admin_user):
def test_group_detail_view_no_permission(create_admin_user):
create_admin_user()
customer = mixer.blend("customers.Customer")
group = mixer.blend("users.AdGroup", customer=customer)
group = mixer.blend("users.Group", customer=customer)
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/ad-group/" + str(group.id) + "/")
response = client.get("/group/" + str(group.id) + "/")
assert response.status_code == 404
def test_ad_group_detail_view_with_user(create_admin_user):
def test_group_detail_view_with_user(create_admin_user):
create_admin_user()
group = mixer.blend("users.AdGroup", customer=mixer.SELECT)
group = mixer.blend("users.Group", customer=mixer.SELECT)
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/ad-group/" + str(group.id) + "/")
response = client.get("/group/" + str(group.id) + "/")
user = mixer.blend("users.User", customer=mixer.SELECT)
user.ad_groups.add(group)
response = client.get("/ad-group/" + str(group.id) + "/")
user.groups.add(group)
response = client.get("/group/" + str(group.id) + "/")
assert response.status_code == 200 and helper.in_content(response, user)

View File

@ -1,52 +0,0 @@
import pytest
from mixer.backend.django import mixer
from django.test import Client
from core.tests import helper
pytestmark = pytest.mark.django_db
def test_mail_group_detail_view_not_logged_in():
response = Client().get("/mail-group/1/")
assert response.status_code == 302 and "login" in response.url
def test_mail_group_detail_view(create_admin_user):
create_admin_user()
group = mixer.blend("users.MailGroup", customer=mixer.SELECT)
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/mail-group/" + str(group.id) + "/")
assert response.status_code == 200 and helper.in_content(response, group)
def test_mail_group_detail_view_not_found(create_admin_user):
create_admin_user()
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/mail-group/230/")
assert response.status_code == 404
def test_mail_group_detail_view_no_permission(create_admin_user):
create_admin_user()
customer = mixer.blend("customers.Customer")
group = mixer.blend("users.MailGroup", customer=customer)
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/mail-group/" + str(group.id) + "/")
assert response.status_code == 404
def test_mail_group_detail_view_with_user(create_admin_user):
create_admin_user()
group = mixer.blend("users.MailGroup", customer=mixer.SELECT)
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/mail-group/" + str(group.id) + "/")
user = mixer.blend("users.User", customer=mixer.SELECT)
user.mail_groups.add(group)
response = client.get("/mail-group/" + str(group.id) + "/")
assert response.status_code == 200 and helper.in_content(response, user)

View File

@ -30,29 +30,16 @@ def test_user_detail_view_not_found(create_admin_user):
assert response.status_code == 404
def test_user_detail_view_ad_group(create_admin_user):
def test_user_detail_view_group(create_admin_user):
create_admin_user()
user = mixer.blend("users.User", customer=mixer.SELECT)
group = mixer.blend("users.AdGroup")
mixer.blend("users.UserInAdGroup", user=user, group=group)
group = mixer.blend("users.Group")
mixer.blend("users.UserInGroup", user=user, group=group)
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/user/" + str(user.id) + "/")
assert response.status_code == 200 and helper.in_content(
response, "AD Groups"
)
def test_user_detail_view_mail_group(create_admin_user):
create_admin_user()
user = mixer.blend("users.User", customer=mixer.SELECT)
group = mixer.blend("users.MailGroup")
mixer.blend("users.UserInMailGroup", user=user, group=group)
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/user/" + str(user.id) + "/")
assert response.status_code == 200 and helper.in_content(
response, "Mail Groups"
response, "Groups"
)

View File

@ -4,19 +4,11 @@ from . import views
urlpatterns = [
path("customer/<int:pk>/groups/", views.groups_table_view, name="groups"),
path("ad-group/<int:pk>/", views.ad_group_detail_view, name="ad_group"),
path("group/<int:pk>/", views.group_detail_view, name="group"),
path(
"mail-group/<int:pk>/", views.mail_group_detail_view, name="mail_group"
),
path(
"delete/ad-group/<int:pk>/",
views.delete_ad_group,
name="ad_group_delete",
),
path(
"delete/mail-group/<int:pk>/",
views.delete_mail_group,
name="mail_group_delete",
"delete/group/<int:pk>/",
views.delete_group,
name="group_delete",
),
path("customer/<int:pk>/users/", views.users_table_view, name="users"),
path("user/<int:pk>/", views.user_detail_view, name="user"),

View File

@ -16,14 +16,11 @@ from computers.models import Computer
from licenses.models import LicenseWithUser
from .decorators import user_view_permission
from .models import AdGroup
from .models import MailGroup
from .models import Group
from .models import MailAlias
from .models import User
from .models import UserInAdGroup
from .models import UserInMailGroup
from .tables import AdGroupsTable
from .tables import MailGroupsTable
from .models import UserInGroup
from .tables import GroupsTable
from .tables import UsersTable
@ -39,8 +36,7 @@ def users_table_view(request, pk):
@user_view_permission
def user_detail_view(request, pk):
user = get_object_or_404(User, pk=pk)
ad_groups = UserInAdGroup.objects.filter(user=user)
mail_groups = UserInMailGroup.objects.filter(user=user)
groups = Group.objects.filter(user=user)
mail_alias = MailAlias.objects.filter(user=user)
computers = Computer.objects.filter(user=user)
licenses = LicenseWithUser.objects.filter(user=user)
@ -49,8 +45,7 @@ def user_detail_view(request, pk):
"users/user_details.html",
{
"user": user,
"ad_groups": ad_groups,
"mail_groups": mail_groups,
"groups": groups,
"mail_alias": mail_alias,
"computers": computers,
"licenses": licenses,
@ -69,34 +64,26 @@ class UserDeleteView(LoginRequiredMixin, DeleteView):
@customer_view_permission
def groups_table_view(request, pk):
customer = get_object_or_404(Customer, pk=pk)
ad_groups_table = AdGroupsTable(
groups_table = GroupsTable(
utils.get_objects_for_customer(
AdGroup, user=request.user, customer_pk=pk
Group, user=request.user, customer_pk=pk
)
)
RequestConfig(request).configure(ad_groups_table)
mail_groups_table = MailGroupsTable(
utils.get_objects_for_customer(
MailGroup, user=request.user, customer_pk=pk
)
)
RequestConfig(request).configure(mail_groups_table)
RequestConfig(request).configure(groups_table)
return TemplateResponse(
request,
"groups/group_list.html",
{
"customer": customer.name,
"ad_groups": ad_groups_table,
"mail_groups": mail_groups_table,
"groups": groups_table,
},
)
@login_required
def ad_group_detail_view(request, pk):
def group_detail_view(request, pk):
group = utils.get_object_with_view_permission(
AdGroup, user=request.user, pk=pk
Group, user=request.user, pk=pk
)
users = group.user_set.all()
return render(
@ -105,37 +92,13 @@ def ad_group_detail_view(request, pk):
@login_required
def mail_group_detail_view(request, pk):
def delete_group(request, pk):
group = utils.get_object_with_view_permission(
MailGroup, user=request.user, pk=pk
)
users = group.user_set.all()
return render(
request, "groups/group_details.html", {"group": group, "users": users}
)
@login_required
def delete_ad_group(request, pk):
group = utils.get_object_with_view_permission(
AdGroup, user=request.user, pk=pk
Group, user=request.user, pk=pk
)
if request.method == "POST":
group.delete()
return redirect("ad_groups", pk=group.customer.pk)
return redirect("groups", pk=group.customer.pk)
return TemplateResponse(
request, "groups/ad_group_confirm_delete.html", {"object": group}
)
@login_required
def delete_mail_group(request, pk):
group = utils.get_object_with_view_permission(
MailGroup, user=request.user, pk=pk
)
if request.method == "POST":
group.delete()
return redirect("mail_groups", pk=group.customer.pk)
return TemplateResponse(
request, "groups/mail_group_confirm_delete.html", {"object": group}
request, "groups/group_confirm_delete.html", {"object": group}
)