diff options
Diffstat (limited to 'ishtar_common/views.py')
-rw-r--r-- | ishtar_common/views.py | 147 |
1 files changed, 116 insertions, 31 deletions
diff --git a/ishtar_common/views.py b/ishtar_common/views.py index b91f3202c..cd22d62eb 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -1490,7 +1490,28 @@ class NewImportView(BaseImportView, CreateView): page_name = _("Import: create (table)") -class EditImportView(BaseImportView, UpdateView): +class ImportPermissionMixin: + permission_full = "change_import" + permission_own = "change_own_import" + + def dispatch(self, request, *args, **kwargs): + import_pk = self.kwargs["pk"] + user = request.user + if not user or not user.ishtaruser: + return redirect("/") + model = models.ImportGroup if self.kwargs.get("group", None) else models.Import + q = model.query_can_access(user, perm=self.permission_full).filter(pk=import_pk) + if not user.is_superuser and not user.ishtaruser.has_right(self.permission_full): + if not user.ishtaruser.has_right(self.permission_own): + return redirect("/") + q = q.filter(Q(importer_type__users__pk=user.ishtaruser.pk)) + if not q.count(): + return redirect("/") + returned = super().dispatch(request, *args, **kwargs) + return returned + + +class EditImportView(ImportPermissionMixin, BaseImportView, UpdateView): page_name = _("Import: edit (table)") @@ -1544,6 +1565,21 @@ class ImportPreFormView(IshtarMixin, LoginRequiredMixin, FormView): return HttpResponseRedirect(self.get_success_url()) +def get_permissions_for_actions(user, imprt, owns, can_edit_all, can_delete_all, can_edit_own, can_delete_own): + can_edit, can_delete = False, False + is_own = None + if can_edit_own or can_delete_own: # need to check owner + if imprt.importer_type_id not in owns: + # "is_own" only query once by importer type + owns[imprt.importer_type.pk] = imprt.importer_type.is_own(user.ishtaruser) + is_own = owns[imprt.importer_type_id] + if can_edit_all or (can_edit_own and is_own): + can_edit = True + if can_delete_all or (can_delete_own and is_own): + can_delete = True + return can_edit, can_delete + + class ImportListView(IshtarMixin, LoginRequiredMixin, ListView): template_name = "ishtar/import_list.html" model = models.Import @@ -1555,15 +1591,31 @@ class ImportListView(IshtarMixin, LoginRequiredMixin, ListView): def get_queryset(self): user = self.request.user - if not user.pk: + if not user.pk or not user.ishtaruser: raise Http404() - q1 = self._queryset_filter(self.model.query_can_access(user)) + q1 = self._queryset_filter(self.model.query_can_access(user, "change_import")) q1 = q1.filter(group__isnull=True).order_by("-end_date", "-creation_date", "-pk") - q2 = self._queryset_filter(models.ImportGroup.query_can_access(user)) + q2 = self._queryset_filter(models.ImportGroup.query_can_access(user, "change_import")) q2 = q2.order_by("-end_date", "-creation_date", "-pk") - return list(reversed(sorted(list(q1) + list(q2), key=lambda x: (x.end_date or x.creation_date)))) + values = list(reversed(sorted(list(q1) + list(q2), key=lambda x: (x.end_date or x.creation_date)))) + can_edit_all, can_delete_all, can_edit_own, can_delete_own = models.Import.get_permissions_for_actions( + user, self.request.session + ) + imports = [] + owns = {} + for imprt in values: + can_edit, can_delete = get_permissions_for_actions( + user, imprt, owns, can_edit_all, can_delete_all, can_edit_own, can_delete_own + ) + imprt.action_list = imprt.get_actions(can_edit=can_edit, can_delete=can_delete) + imports.append(imprt) + return imports def post(self, request, *args, **kwargs): + can_edit_all, can_delete_all, can_edit_own, can_delete_own = models.Import.get_permissions_for_actions( + request.user, request.session + ) + owns = {} for field in request.POST: if not field.startswith("import-action-") or not request.POST[field]: continue @@ -1576,28 +1628,26 @@ class ImportListView(IshtarMixin, LoginRequiredMixin, ListView): imprt = model.objects.get(pk=int(field.split("-")[-1])) except (models.Import.DoesNotExist, ValueError): continue - if not self.request.user.is_superuser: - # user can only edit his own imports - user = models.IshtarUser.objects.get(pk=self.request.user.pk) - if imprt.user != user: - continue + can_edit, can_delete = get_permissions_for_actions( + request.user, imprt, owns, can_edit_all, can_delete_all, can_edit_own, can_delete_own + ) action = request.POST[field] - if action == "D": + if can_delete and action == "D": url = "import_group_delete" if is_group else "import_delete" return HttpResponseRedirect( reverse(url, kwargs={"pk": imprt.pk}) ) - elif action == "ED": + elif can_edit and action == "ED": url = "edit_import_group" if is_group else "edit_import" return HttpResponseRedirect( reverse(url, kwargs={"pk": imprt.pk}) ) - elif action == "A": + elif can_edit and action == "A": imprt.initialize( user=self.request.user.ishtaruser, session_key=request.session.session_key, ) - elif action == "I": + elif can_edit and action == "I": if settings.USE_BACKGROUND_TASK: imprt.delayed_importation(request, request.session.session_key) else: @@ -1612,12 +1662,12 @@ class ImportListView(IshtarMixin, LoginRequiredMixin, ListView): f"{imprt} - {e}", "warning", ) - elif action == "CH": + elif can_edit and action == "CH": if settings.USE_BACKGROUND_TASK: imprt.delayed_check_modified(request.session.session_key) else: imprt.check_modified() - elif action == "IS": + elif can_edit and action == "IS": if imprt.current_line is None: imprt.current_line = imprt.skip_lines imprt.save() @@ -1626,19 +1676,37 @@ class ImportListView(IshtarMixin, LoginRequiredMixin, ListView): "import_step_by_step", args=[imprt.pk, imprt.current_line + 1] ) ) - elif action == "AC": + elif can_edit and action == "AC": imprt.archive() - elif action in ("F", "FE"): + elif can_edit and action in ("F", "FE"): imprt.unarchive(action) return HttpResponseRedirect(reverse(self.current_url)) def get_context_data(self, **kwargs): dct = super().get_context_data(**kwargs) + add_import_perm = self.request.user.ishtaruser.has_right("add_import", session=self.request.session) + import_type_table = models.ImporterType.objects.filter(available=True, is_import=True, type='tab') + import_type_gis = models.ImporterType.objects.filter(available=True, is_import=True, type='gis') + import_type_group = models.ImporterGroup.objects.filter(available=True) + if not add_import_perm and self.request.user.ishtaruser.has_right("add_own_import", + session=self.request.session): + import_type_table = import_type_table.filter(users__pk=self.request.user.ishtaruser.pk) + import_type_gis = import_type_gis.filter(users__pk=self.request.user.ishtaruser.pk) + import_type_group = import_type_group.filter(users__pk=self.request.user.ishtaruser.pk) + add_import_perm = True + has_import_table, has_import_gis, has_import_group = False, False, False + if add_import_perm: + if import_type_table.count(): + has_import_table = True + if import_type_gis.count(): + has_import_gis = True + if import_type_group.count(): + has_import_group = True dct.update({ - "autorefresh_available": settings.USE_BACKGROUND_TASK, - "has_import_table": models.ImporterType.objects.filter(available=True, is_import=True, type='tab').count(), - "has_import_gis": models.ImporterType.objects.filter(available=True, is_import=True, type='gis').count(), - "has_import_group": models.ImporterGroup.objects.filter(available=True).count(), + "has_import_table": has_import_table, + "has_import_gis": has_import_gis, + "has_import_group": has_import_group, + "can_create_import": has_import_table or has_import_gis or has_import_group, }) return dct @@ -2083,14 +2151,23 @@ def import_get_status(request, current_right=None): "number_of_line": item.number_of_line, "progress_percent": item.progress_percent, }) - item_dct["actions"] = [(key, str(lbl)) for key, lbl in item.get_actions()] + can_edit_all, can_delete_all, can_edit_own, can_delete_own = models.Import.get_permissions_for_actions( + request.user + ) + can_edit, can_delete = get_permissions_for_actions( + request.user, item, {}, can_edit_all, can_delete_all, can_edit_own, can_delete_own + ) + item_dct["actions"] = [ + (key, str(lbl)) + for key, lbl in item.get_actions(can_edit=can_edit, can_delete=can_delete) + ] response[key].append(item_dct) data = json.dumps(response) return HttpResponse(data, content_type="application/json") -class ImportLinkView(IshtarMixin, LoginRequiredMixin, ModelFormSetView): +class ImportMatchView(ImportPermissionMixin, IshtarMixin, LoginRequiredMixin, ModelFormSetView): template_name = "ishtar/formset_import_match.html" model = models.TargetKey page_name = _("Link unmatched items") @@ -2100,9 +2177,11 @@ class ImportLinkView(IshtarMixin, LoginRequiredMixin, ModelFormSetView): form_class = forms.TargetKeyForm formset_class = forms.TargetKeyFormset max_fields = 250 + permission_full = "change_import" + permission_own = "change_own_import" def get_formset_kwargs(self): - kwargs = super(ImportLinkView, self).get_formset_kwargs() + kwargs = super().get_formset_kwargs() kwargs["user"] = self.request.user return kwargs @@ -2126,25 +2205,29 @@ class ImportLinkView(IshtarMixin, LoginRequiredMixin, ModelFormSetView): return reverse("import_link_unmatched", args=[self.kwargs["pk"]]) -class ImportDeleteView(IshtarMixin, LoginRequiredMixin, DeleteView): +class ImportDeleteView(ImportPermissionMixin, IshtarMixin, LoginRequiredMixin, DeleteView): template_name = "ishtar/import_delete.html" model = models.Import page_name = _("Delete import") + permission_full = "delete_import" + permission_own = "delete_own_import" def get_success_url(self): return reverse("current_imports") -class ImportGroupDeleteView(IshtarMixin, LoginRequiredMixin, DeleteView): +class ImportGroupDeleteView(ImportPermissionMixin, IshtarMixin, LoginRequiredMixin, DeleteView): template_name = "ishtar/import_delete.html" model = models.ImportGroup page_name = _("Delete import") + permission_full = "delete_import" + permission_own = "delete_own_import" def get_success_url(self): return reverse("current_imports") -class ImportCSVView(IshtarMixin, LoginRequiredMixin, TemplateView): +class ImportCSVView(ImportPermissionMixin, IshtarMixin, LoginRequiredMixin, TemplateView): template_name = "ishtar/blocks/view_import_csv.html" ATTRIBUTES = { "source": "get_imported_values", @@ -2158,13 +2241,15 @@ class ImportCSVView(IshtarMixin, LoginRequiredMixin, TemplateView): "result": ("fa fa-th", _("Result")) , "match": ("fa fa-arrows-h", _("Match")), } + permission_full = "view_import" + permission_own = "view_own_import" def get(self, request, *args, **kwargs): user = self.request.user if not user.pk: raise Http404() model = models.ImportGroup if kwargs.get("group", None) else models.Import - q = model.query_can_access(self.request.user).filter(pk=kwargs.get("pk", -1)) + q = model.query_can_access(self.request.user, perm=self.permission_full).filter(pk=kwargs.get("pk", -1)) if not q.count(): raise Http404() self.import_item = q.all()[0] @@ -2208,7 +2293,7 @@ class ImportCSVView(IshtarMixin, LoginRequiredMixin, TemplateView): return data -def line_error(request, line_id): +def line_error(request, line_id, current_right=None): """ Set or unset ignored state of a csv error file """ @@ -2219,7 +2304,7 @@ def line_error(request, line_id): if not q.count(): return line = q.all()[0] - q = models.Import.query_can_access(request.user).filter(pk=line.import_item_id) + q = models.Import.query_can_access(request.user, perm="change_import").filter(pk=line.import_item_id) if not q.count(): raise Http404() line.ignored = not line.ignored |