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 | 
