Skip to content

Commit

Permalink
Implementer rettighed til at anonymisere personer
Browse files Browse the repository at this point in the history
  • Loading branch information
rasmusselsmark committed Jan 31, 2025
1 parent 04b9542 commit 37012c1
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 14 deletions.
20 changes: 18 additions & 2 deletions members/admin/person_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.utils.html import format_html
from requests import request

from members.models import (
Department,
Expand Down Expand Up @@ -62,7 +63,6 @@ class PersonAdmin(admin.ModelAdmin):
AdminActions.invite_many_to_activity_action,
"export_emaillist",
"export_csv",
"anonymize_persons",
]
raw_id_fields = ("family", "user")

Expand All @@ -74,6 +74,18 @@ class PersonAdmin(admin.ModelAdmin):
EmailItemInline,
]

def get_actions(self, request):
actions = super().get_actions(request)

if request.user.has_perm("members.anonymize_persons"):
actions["anonymize_persons"] = (
lambda modeladmin, request, queryset: self.anonymize_persons(request, queryset),
"anonymize_persons",
self.anonymize_persons.short_description,
)

return actions

def family_url(self, item):
return format_html(
'<a href="../family/%d">%s</a>' % (item.family.id, item.family.email)
Expand Down Expand Up @@ -236,6 +248,10 @@ class MassConfirmForm(forms.Form):
),
)

if not request.user.has_perm("members.anonymize_persons"):
self.message_user(request, "Du har ikke tilladelse til at anonymisere personer.")
return HttpResponseRedirect(request.get_full_path())

persons = queryset

context = admin.site.each_context(request)
Expand All @@ -248,7 +264,7 @@ class MassConfirmForm(forms.Form):
if form.is_valid():
context["mass_confirmation_form"] = form
for person in queryset:
person.anonymize()
person.anonymize(request)

self.message_user(request, "Valgte personer er blevet anonymiseret.")
return HttpResponseRedirect(request.get_full_path())
Expand Down
29 changes: 29 additions & 0 deletions members/migrations/0065_alter_person_options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.17 on 2025-01-27 18:42

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("members", "0064_family_anonymized_person_anonymized"),
]

operations = [
migrations.AlterModelOptions(
name="person",
options={
"ordering": ["added_at"],
"permissions": (
(
"view_full_address",
"Can view persons full address + phonenumber + email",
),
("view_all_persons", "Can view persons not related to department"),
("anonymize_persons", "Can anonymize persons"),
),
"verbose_name": "Person",
"verbose_name_plural": "Personer",
},
),
]
13 changes: 10 additions & 3 deletions members/models/family.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import uuid
from django.db import models
from django.urls import reverse
from django.core.exceptions import PermissionDenied

from .person import Person
import members.models.emailtemplate
Expand Down Expand Up @@ -59,7 +60,10 @@ def save(self, *args, **kwargs):
self.email = self.email.lower()
return super(Family, self).save(*args, **kwargs)

def anonymize(self):
def anonymize(self, request):
if not request.user.has_perm("members.anonymize_persons"):
raise PermissionDenied("Du har ikke tilladelse til at anonymisere personer eller familier.")

non_anonymized_persons_in_family = self.person_set.filter(anonymized=False)
if non_anonymized_persons_in_family.count() != 0:
raise Exception("Cannot anonymize family with non-anonymized persons.")
Expand All @@ -69,7 +73,10 @@ def anonymize(self):
self.anonymized = True
self.save()

def anonymize_if_all_persons_anonymized(self):
def anonymize_if_all_persons_anonymized(self, request):
if not request.user.has_perm("members.anonymize_persons"):
raise PermissionDenied("Du har ikke tilladelse til at anonymisere personer eller familier.")

non_anonymized_persons_in_family = self.person_set.filter(anonymized=False)
if non_anonymized_persons_in_family.count() == 0:
self.anonymize()
self.anonymize(request)
17 changes: 14 additions & 3 deletions members/models/person.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.utils import timezone
from django.conf import settings
from members.models.municipality import Municipality
from django.core.exceptions import PermissionDenied
from members.utils.address import format_address
from urllib.parse import quote_plus
import requests
Expand All @@ -21,7 +22,14 @@ class Meta:
"view_full_address",
"Can view persons full address + phonenumber + email",
),
("view_all_persons", "Can view persons not related to department"),
(
"view_all_persons",
"Can view persons not related to department",
),
(
"anonymize_persons",
"Can anonymize persons",
),
)

PARENT = "PA"
Expand Down Expand Up @@ -191,7 +199,10 @@ def update_dawa_data(self):

# TODO: Move to dawa_data in utils

def anonymize(self):
def anonymize(self, request):
if not request.user.has_perm("members.anonymize_persons"):
raise PermissionDenied("Du har ikke tilladelse til at anonymisere personer.")

logger.info(f"Anonymizing person {self.name}")

self.name = "Anonymiseret"
Expand Down Expand Up @@ -222,7 +233,7 @@ def anonymize(self):
self.anonymized = True
self.save()

self.family.anonymize_if_all_persons_anonymized()
self.family.anonymize_if_all_persons_anonymized(request)

firstname.admin_order_field = "name"
firstname.short_description = "Fornavn"
10 changes: 9 additions & 1 deletion members/tests/test_model_family.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,18 @@ def test_get_children(self):
# family = FamilyFactory()
# self.assertEqual("family_form", family.get_absolute_url())

def create_request_with_permission(self, permission):
return type('Request', (object,), {
'user': type('User', (object,), {
'has_perm': lambda self, perm: perm == permission
})()
})()

def test_anonymize_family_with_no_members(self):
family = FamilyFactory(dont_send_mails=False)

family.anonymize()
request = self.create_request_with_permission("members.anonymize_persons")
family.anonymize(request)

self.assertEquals(family.email, f"anonym-{family.id}@codingpirates.dk")
self.assertTrue(family.dont_send_mails)
Expand Down
28 changes: 23 additions & 5 deletions members/tests/test_model_person.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from django.test import TestCase
from django.core.exceptions import ValidationError
from django.core.exceptions import ValidationError, PermissionDenied
from members.models.person import Person
from datetime import datetime
from freezegun import freeze_time
Expand Down Expand Up @@ -79,12 +79,28 @@ def test_defaults_to_no_certificate(self):
person = PersonFactory()
self.assertEqual(person.has_certificate, None)

def create_request_with_permission(self, permission):
return type('Request', (object,), {
'user': type('User', (object,), {
'has_perm': lambda self, perm: perm == permission
})()
})()

def test_anonymize_person_in_single_member_family_no_permission(self):
person = PersonFactory()

request = self.create_request_with_permission("members.non_existing_permission")
with self.assertRaises(PermissionDenied):
person.anonymize(request)


def test_anonymize_person_in_single_member_family(self):
person = PersonFactory()
birthday = person.birthday
municipality = person.municipality

person.anonymize()
request = self.create_request_with_permission("members.anonymize_persons")
person.anonymize(request)

self.assertTrue(person.anonymized)
self.assertEqual(person.name, "Anonymiseret")
Expand All @@ -108,7 +124,8 @@ def test_anonymize_single_person_in_multi_member_family(self):
# sanity check that they are in the same family
self.assertEquals(person_1.family, person_2.family)

person_1.anonymize()
request = self.create_request_with_permission("members.anonymize_persons")
person_1.anonymize(request)

self.assertTrue(person_1.anonymized)
self.assertFalse(person_2.anonymized)
Expand All @@ -119,16 +136,17 @@ def test_anonymize_single_person_in_multi_member_family(self):
def test_anonymize_all_persons_in_multi_member_family(self):
person_1 = PersonFactory()
person_2 = PersonFactory(family=person_1.family)
request = self.create_request_with_permission("members.anonymize_persons")

# sanity check that are are pointing to same family object
self.assertEquals(person_1.family, person_2.family)

person_1.anonymize()
person_1.anonymize(request)

self.assertTrue(person_1.anonymized)
self.assertFalse(person_1.family.anonymized) # not yet anonymized

person_2.anonymize()
person_2.anonymize(request)

self.assertTrue(person_2.anonymized)
self.assertTrue(person_2.family.anonymized)

0 comments on commit 37012c1

Please sign in to comment.