Default group required

* adds access checks depending on the current group confgiguration of a user
* removes buttons for adding/editing or removing data if default group is not set for a user
* removes buttons for adding/removing related data in unshared interventions
* removes shared-user setting from share menu of an intervention if user is not zb or ets
* renames has_access() from intervention Model into is_shared_with() for more clarity
* fixes bug in group check in_group() from utils.py
This commit is contained in:
mipel 2021-08-02 16:23:29 +02:00
parent 63b2d3ef66
commit f58650effa
10 changed files with 62 additions and 19 deletions

View File

@ -42,12 +42,14 @@ def index_view(request: HttpRequest):
@login_required @login_required
@default_group_required
def new_view(request: HttpRequest): def new_view(request: HttpRequest):
# ToDo # ToDo
pass pass
@login_required @login_required
@default_group_required
def edit_view(request: HttpRequest, id: str): def edit_view(request: HttpRequest, id: str):
# ToDo # ToDo
pass pass
@ -106,12 +108,14 @@ def account_index_view(request: HttpRequest):
@login_required @login_required
@default_group_required
def account_new_view(request: HttpRequest): def account_new_view(request: HttpRequest):
# ToDo # ToDo
pass pass
@login_required @login_required
@default_group_required
def account_edit_view(request: HttpRequest, id: str): def account_edit_view(request: HttpRequest, id: str):
# ToDo # ToDo
pass pass
@ -130,6 +134,7 @@ def account_remove_view(request: HttpRequest, id: str):
@login_required @login_required
@default_group_required
def new_payment_view(request: HttpRequest, intervention_id: str): def new_payment_view(request: HttpRequest, intervention_id: str):
""" Renders a modal view for adding new payments """ Renders a modal view for adding new payments
@ -168,6 +173,7 @@ def new_payment_view(request: HttpRequest, intervention_id: str):
@login_required @login_required
@default_group_required
def payment_remove_view(request: HttpRequest, id: str): def payment_remove_view(request: HttpRequest, id: str):
""" Renders a modal view for removing payments """ Renders a modal view for removing payments
@ -187,6 +193,7 @@ def payment_remove_view(request: HttpRequest, id: str):
@login_required @login_required
@default_group_required
def withdraw_remove_view(request: HttpRequest, id: str, withdraw_id: str): def withdraw_remove_view(request: HttpRequest, id: str, withdraw_id: str):
""" Renders a modal view for removing withdraws """ Renders a modal view for removing withdraws

View File

@ -18,7 +18,8 @@ from intervention.models import Intervention
from konova.enums import UserActionLogEntryEnum from konova.enums import UserActionLogEntryEnum
from konova.forms import BaseForm, BaseModalForm from konova.forms import BaseForm, BaseModalForm
from konova.models import Document from konova.models import Document
from konova.settings import DEFAULT_LAT, DEFAULT_LON, DEFAULT_ZOOM from konova.settings import DEFAULT_LAT, DEFAULT_LON, DEFAULT_ZOOM, ZB_GROUP, ETS_GROUP
from konova.utils.user_checks import in_group
from organisation.models import Organisation from organisation.models import Organisation
from user.models import UserActionLogEntry from user.models import UserActionLogEntry
@ -293,18 +294,22 @@ class ShareInterventionForm(BaseModalForm):
) )
# Initialize users field # Initialize users field
users = self.instance.users.all() # Remove field if user is not in registration or conservation group
choices = [] if not in_group(self.request.user, ZB_GROUP) and not in_group(self.request.user, ETS_GROUP):
for n in users: del self.fields["users"]
choices.append( else:
(n.id, n.username) users = self.instance.users.all()
choices = []
for n in users:
choices.append(
(n.id, n.username)
)
self.fields["users"].choices = choices
u_ids = list(users.values_list("id", flat=True))
self.initialize_form_field(
"users",
u_ids
) )
self.fields["users"].choices = choices
u_ids = list(users.values_list("id", flat=True))
self.initialize_form_field(
"users",
u_ids
)
def save(self): def save(self):
accessing_users = User.objects.filter( accessing_users = User.objects.filter(

View File

@ -207,7 +207,7 @@ class Intervention(BaseObject):
self.identifier = new_id self.identifier = new_id
super().save(*args, **kwargs) super().save(*args, **kwargs)
def has_access(self, user: User): def is_shared_with(self, user: User):
""" Access check """ Access check
Checks whether a given user has access to this intervention Checks whether a given user has access to this intervention

View File

@ -10,12 +10,14 @@
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
<a href="{% url 'compensation:new' %}" title="{% trans 'Add new compensation' %}"> <a href="{% url 'compensation:new' %}" title="{% trans 'Add new compensation' %}">
<button class="btn btn-outline-default"> <button class="btn btn-outline-default">
{% fa5_icon 'plus' %} {% fa5_icon 'plus' %}
{% fa5_icon 'leaf' %} {% fa5_icon 'leaf' %}
</button> </button>
</a> </a>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
@ -45,9 +47,11 @@
</td> </td>
<td class="align-middle">{{ comp.title }}</td> <td class="align-middle">{{ comp.title }}</td>
<td> <td>
{% if is_default_member and has_access %}
<button data-form-url="{% url 'compensation:remove' comp.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove compensation' %}"> <button data-form-url="{% url 'compensation:remove' comp.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove compensation' %}">
{% fa5_icon 'trash' %} {% fa5_icon 'trash' %}
</button> </button>
{% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -10,10 +10,12 @@
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'intervention:new-doc' intervention.id %}" title="{% trans 'Add new document' %}"> <button class="btn btn-outline-default btn-modal" data-form-url="{% url 'intervention:new-doc' intervention.id %}" title="{% trans 'Add new document' %}">
{% fa5_icon 'plus' %} {% fa5_icon 'plus' %}
{% fa5_icon 'file' %} {% fa5_icon 'file' %}
</button> </button>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
@ -43,9 +45,11 @@
</td> </td>
<td class="align-middle">{{ doc.comment }}</td> <td class="align-middle">{{ doc.comment }}</td>
<td> <td>
{% if is_default_member and has_access %}
<button data-form-url="{% url 'doc-remove' doc.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove document' %}"> <button data-form-url="{% url 'doc-remove' doc.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove document' %}">
{% fa5_icon 'trash' %} {% fa5_icon 'trash' %}
</button> </button>
{% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -10,12 +10,14 @@
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
<a href="{% url 'compensation:new' %}" title="{% trans 'Add new withdraw' %}"> <a href="{% url 'compensation:new' %}" title="{% trans 'Add new withdraw' %}">
<button class="btn btn-outline-default"> <button class="btn btn-outline-default">
{% fa5_icon 'plus' %} {% fa5_icon 'plus' %}
{% fa5_icon 'tree' %} {% fa5_icon 'tree' %}
</button> </button>
</a> </a>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
@ -45,9 +47,11 @@
</td> </td>
<td class="align-middle">{{ withdraw.amount|floatformat:2 }} %</td> <td class="align-middle">{{ withdraw.amount|floatformat:2 }} %</td>
<td> <td>
{% if is_default_member and has_access %}
<button data-form-url="{% url 'compensation:withdraw-remove' withdraw.account.id withdraw.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove Withdraw' %}"> <button data-form-url="{% url 'compensation:withdraw-remove' withdraw.account.id withdraw.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove Withdraw' %}">
{% fa5_icon 'trash' %} {% fa5_icon 'trash' %}
</button> </button>
{% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -10,10 +10,12 @@
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
{% if is_default_member and has_access %}
<button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:pay-new' intervention.id %}" title="{% trans 'Add new payment' %}"> <button class="btn btn-outline-default btn-modal" data-form-url="{% url 'compensation:pay-new' intervention.id %}" title="{% trans 'Add new payment' %}">
{% fa5_icon 'plus' %} {% fa5_icon 'plus' %}
{% fa5_icon 'money-bill-wave' %} {% fa5_icon 'money-bill-wave' %}
</button> </button>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
@ -47,9 +49,11 @@
<td class="align-middle">{{ pay.due_on }}</td> <td class="align-middle">{{ pay.due_on }}</td>
<td class="align-middle">{{ pay.comment }}</td> <td class="align-middle">{{ pay.comment }}</td>
<td> <td>
{% if is_default_member and has_access %}
<button data-form-url="{% url 'compensation:pay-remove' pay.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove payment' %}"> <button data-form-url="{% url 'compensation:pay-remove' pay.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove payment' %}">
{% fa5_icon 'trash' %} {% fa5_icon 'trash' %}
</button> </button>
{% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -27,16 +27,21 @@
<button class="btn btn-default btn-modal mr-2" title="{% trans 'Share' %}" data-form-url="{% url 'intervention:share-create' intervention.id %}"> <button class="btn btn-default btn-modal mr-2" title="{% trans 'Share' %}" data-form-url="{% url 'intervention:share-create' intervention.id %}">
{% fa5_icon 'share-alt' %} {% fa5_icon 'share-alt' %}
</button> </button>
{% if is_zb_member %}
<a href="{% url 'home' %}" class="mr-2"> <a href="{% url 'home' %}" class="mr-2">
<button class="btn btn-default" title="{% trans 'Run check' %}"> <button class="btn btn-default" title="{% trans 'Run check' %}">
{% fa5_icon 'star' %} {% fa5_icon 'star' %}
</button> </button>
</a> </a>
{% endif %}
{% if is_ets_member %}
<a href="{% url 'home' %}" class="mr-2"> <a href="{% url 'home' %}" class="mr-2">
<button class="btn btn-default" title="{% trans 'Record' %}"> <button class="btn btn-default" title="{% trans 'Record' %}">
{% fa5_icon 'bookmark' %} {% fa5_icon 'bookmark' %}
</button> </button>
</a> </a>
{% endif %}
{% if is_default_member %}
<a href="{% url 'home' %}" class="mr-2"> <a href="{% url 'home' %}" class="mr-2">
<button class="btn btn-default" title="{% trans 'Edit' %}"> <button class="btn btn-default" title="{% trans 'Edit' %}">
{% fa5_icon 'edit' %} {% fa5_icon 'edit' %}
@ -46,6 +51,7 @@
{% fa5_icon 'trash' %} {% fa5_icon 'trash' %}
</button> </button>
{% endif %} {% endif %}
{% endif %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -11,6 +11,7 @@ from konova.contexts import BaseContext
from konova.decorators import * from konova.decorators import *
from konova.forms import SimpleGeomForm, NewDocumentForm, RemoveModalForm from konova.forms import SimpleGeomForm, NewDocumentForm, RemoveModalForm
from konova.utils.message_templates import FORM_INVALID from konova.utils.message_templates import FORM_INVALID
from konova.utils.user_checks import in_group
@login_required @login_required
@ -45,6 +46,7 @@ def index_view(request: HttpRequest):
@login_required @login_required
@default_group_required
def new_view(request: HttpRequest): def new_view(request: HttpRequest):
""" """
Renders a view for a new intervention creation Renders a view for a new intervention creation
@ -130,7 +132,8 @@ def open_view(request: HttpRequest, id: str):
compensations = intervention.compensations.filter( compensations = intervention.compensations.filter(
deleted=None, deleted=None,
) )
has_access = intervention.has_access(user=request.user) _user = request.user
is_data_shared = intervention.is_shared_with(user=_user)
geom_form = SimpleGeomForm( geom_form = SimpleGeomForm(
instance=intervention instance=intervention
@ -139,11 +142,14 @@ def open_view(request: HttpRequest, id: str):
context = { context = {
"intervention": intervention, "intervention": intervention,
"compensations": compensations, "compensations": compensations,
"has_access": has_access, "has_access": is_data_shared,
"geom_form": geom_form, "geom_form": geom_form,
"is_default_member": in_group(_user, _(DEFAULT_GROUP)),
"is_zb_member": in_group(_user, _(ZB_GROUP)),
"is_ets_member": in_group(_user, _(ETS_GROUP)),
} }
if not has_access: if not is_data_shared:
messages.info(request, _("Remember: This data has not been shared with you, yet. This means you can only read but can not edit or perform any actions like running a check or recording.")) messages.info(request, _("Remember: This data has not been shared with you, yet. This means you can only read but can not edit or perform any actions like running a check or recording."))
context = BaseContext(request, context).context context = BaseContext(request, context).context
@ -180,6 +186,7 @@ def edit_view(request: HttpRequest, id: str):
@login_required @login_required
@default_group_required
def remove_view(request: HttpRequest, id: str): def remove_view(request: HttpRequest, id: str):
""" Renders a remove view for this intervention """ Renders a remove view for this intervention
@ -219,7 +226,7 @@ def share_view(request: HttpRequest, id: str, token: str):
# Check tokens # Check tokens
if intervention.access_token == token: if intervention.access_token == token:
# Send different messages in case user has already been added to list of sharing users # Send different messages in case user has already been added to list of sharing users
if intervention.has_access(user): if intervention.is_shared_with(user):
messages.info( messages.info(
request, request,
_("{} has already been shared with you").format(intervention.identifier) _("{} has already been shared with you").format(intervention.identifier)
@ -251,7 +258,6 @@ def create_share_view(request: HttpRequest, id: str):
Returns: Returns:
""" """
user = request.user
intervention = get_object_or_404(Intervention, id=id) intervention = get_object_or_404(Intervention, id=id)
form = ShareInterventionForm(request.POST or None, instance=intervention, request=request) form = ShareInterventionForm(request.POST or None, instance=intervention, request=request)
if request.method == "POST": if request.method == "POST":

View File

@ -5,6 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 02.07.21 Created on: 02.07.21
""" """
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User from django.contrib.auth.models import User
@ -18,4 +19,6 @@ def in_group(user: User, group: str) -> bool:
Returns: Returns:
bool bool
""" """
return group in user.groups.values("name") return user.groups.filter(
name=_(group)
)