diff --git a/aleksis/core/menus.py b/aleksis/core/menus.py index f50d559f6fc19f27d33c8a2b9a6be548f41ab2ec..911b5b32a6c68f483ed882b0fac219bb4c6203dc 100644 --- a/aleksis/core/menus.py +++ b/aleksis/core/menus.py @@ -124,16 +124,15 @@ MENUS = { "url": "#", "icon": "people", "root": True, - "validators": [ - "menu_generator.validators.is_authenticated", - "aleksis.core.util.core_helpers.has_person", - ], + "validators": [("aleksis.core.util.predicates.permission_validator", "core.view_people_menu")], "submenu": [ { "name": _("Persons"), "url": "persons", "icon": "person", - "validators": ["menu_generator.validators.is_authenticated"], + "validators": [ + ("aleksis.core.util.predicates.permission_validator", "core.view_persons") + ], }, { "name": _("Groups"), diff --git a/aleksis/core/rules.py b/aleksis/core/rules.py index b2406a0b6c02d3001d0d5e52b44008b0f9c545ec..f9b87f3d7bc49946022e9ee6612aeaed5706440c 100644 --- a/aleksis/core/rules.py +++ b/aleksis/core/rules.py @@ -1,13 +1,34 @@ +from rules import add_perm, always_allow -from rules import predicate, add_perm +from aleksis.core.models import Person +from aleksis.core.util.predicates import ( + has_person_predicate, + has_global_perm, + has_any_object, + is_person, + has_object_perm, +) -from aleksis.core.util.core_helpers import has_person -print("rules?") +add_perm("core", always_allow) -@predicate -def has_person_predicate(user): - # return has_person(user) - return True +# View persons +view_persons_predicate = has_person_predicate & ( + has_global_perm("core.view_person") | has_any_object("core.view_person", Person) +) +add_perm("core.view_persons", view_persons_predicate) -add_perm('core.view_person', has_person_predicate) \ No newline at end of file +# View person +view_person_predicate = has_person_predicate & ( + has_global_perm("core.view_person") | has_object_perm("core.view_person") | is_person +) +add_perm("core.view_person", view_person_predicate) + +# Change person +change_person_predicate = has_person_predicate & ( + has_global_perm("core.change_person") | has_object_perm("core.change_person") +) +add_perm("core.change_person", change_person_predicate) + +# People menu (persons + objects) +add_perm("core.view_people_menu", has_person_predicate & (view_persons_predicate)) diff --git a/aleksis/core/templates/core/person_full.html b/aleksis/core/templates/core/person_full.html index 8f9ceed60aa7ca1a99bde9e3682f5988d2f29f75..73e099fea3bad329d74b8065dc62a0521fc3ba21 100644 --- a/aleksis/core/templates/core/person_full.html +++ b/aleksis/core/templates/core/person_full.html @@ -2,19 +2,23 @@ {% extends "core/base.html" %} -{% load i18n static cropping %} +{% load i18n static cropping rules %} {% load render_table from django_tables2 %} {% block browser_title %}{{ person.first_name }} {{ person.last_name }}{% endblock %} {% block content %} <h4>{{ person.first_name }} {{ person.last_name }}</h4> - <p> - <a href="{% url 'edit_person_by_id' person.id %}" class="btn waves-effect waves-light"> - <i class="material-icons left">edit</i> - {% trans "Edit" %} - </a> - </p> + + {% has_perm 'core.change_person' user person as can_change_person %} + {% if can_change_person %} + <p> + <a href="{% url 'edit_person_by_id' person.id %}" class="btn waves-effect waves-light"> + <i class="material-icons left">edit</i> + {% trans "Edit" %} + </a> + </p> + {% endif %} <h5>{% blocktrans %}Contact details{% endblocktrans %}</h5> <div class="row"> diff --git a/aleksis/core/views.py b/aleksis/core/views.py index 5608d1d608efb5f0119c19d27909284bf4afde67..61548dede9903a0da5c5953a303311b3eebc3caa 100644 --- a/aleksis/core/views.py +++ b/aleksis/core/views.py @@ -7,6 +7,8 @@ from django.shortcuts import get_object_or_404, redirect, render from django.utils.translation import ugettext_lazy as _ from django_tables2 import RequestConfig +from guardian.shortcuts import get_objects_for_user +from rules.contrib.views import permission_required, objectgetter from .decorators import admin_required, person_required from .forms import ( @@ -50,12 +52,14 @@ def offline(request): return render(request, "core/offline.html") -@login_required +@permission_required("core.view_persons") def persons(request: HttpRequest) -> HttpResponse: context = {} # Get all persons - persons = Person.objects.filter(is_active=True) + persons = get_objects_for_user( + request.user, "core.view_person", Person.objects.filter(is_active=True) + ) # Build table persons_table = PersonsTable(persons) @@ -65,24 +69,24 @@ def persons(request: HttpRequest) -> HttpResponse: return render(request, "core/persons.html", context) -@login_required +def get_person_by_pk(request, id_: Optional[int] = None): + if id_: + return get_object_or_404(Person, pk=id_) + else: + return request.user.person + + +@permission_required("core.view_person", fn=get_person_by_pk) def person(request: HttpRequest, id_: Optional[int] = None) -> HttpResponse: context = {} # Get person and check access - try: - if id_ is None: - person = request.user.person - else: - person = Person.objects.get(pk=id_) - except Person.DoesNotExist as e: - # Turn not-found object into a 404 error - raise Http404 from e + person = get_person_by_pk(request, id_) context["person"] = person # Get groups where person is member of - groups = Group.objects.filter(members=id_) + groups = Group.objects.filter(members=person.pk) # Build table groups_table = GroupsTable(groups) @@ -158,7 +162,7 @@ def persons_accounts(request: HttpRequest) -> HttpResponse: return render(request, "core/persons_accounts.html", context) -@admin_required +@permission_required("core.change_person", fn=objectgetter(Person, "id_")) def edit_person(request: HttpRequest, id_: int) -> HttpResponse: context = {}