diff options
Diffstat (limited to 'ishtar_common')
-rw-r--r-- | ishtar_common/admin.py | 1 | ||||
-rw-r--r-- | ishtar_common/tests.py | 4 | ||||
-rw-r--r-- | ishtar_common/views.py | 130 | ||||
-rw-r--r-- | ishtar_common/views_item.py | 47 |
4 files changed, 98 insertions, 84 deletions
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py index 6fda81283..cc26d6253 100644 --- a/ishtar_common/admin.py +++ b/ishtar_common/admin.py @@ -1871,7 +1871,6 @@ class ProfileTypeAdmin(GeneralTypeAdmin): ) ) - def check_permission(self, request, object_id): # check that all "own" permission has a request associated try: diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py index 32e1f12a8..daa814a94 100644 --- a/ishtar_common/tests.py +++ b/ishtar_common/tests.py @@ -1517,7 +1517,9 @@ class AutocompleteTestBase: self.assertEqual( response.status_code, 200, msg="Status code != 200 - {}".format(url) ) - data = json.loads(response.content.decode()) + result = response.content.decode() + self.assertTrue(result) + data = json.loads(result) self.assertEqual( len(data), 1, diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 6411441f1..3a7dc06b7 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -98,11 +98,12 @@ from ishtar_common import tasks from .views_item import ( check_permission, display_item, + get_autocomplete_query, get_item, - show_item, - new_qa_item, - modify_qa_item, get_short_html_detail, + modify_qa_item, + new_qa_item, + show_item, ) convert_document = None @@ -866,10 +867,8 @@ def autocomplete_person_permissive( def autocomplete_user(request): - ishtaruser = getattr(request.user, "ishtaruser", None) - if not ishtaruser: - return HttpResponse("[]", content_type="text/plain") - if not ishtaruser.has_permission("ishtar_common.view_person"): + query = get_autocomplete_query(request, "ishtar_common", "view_person") + if query: return HttpResponse("[]", content_type="text/plain") q = request.GET.get("term") limit = request.GET.get("limit", 20) @@ -877,7 +876,6 @@ def autocomplete_user(request): limit = int(limit) except ValueError: return HttpResponseBadRequest() - query = Q() for q in q.split(" "): qu = ( Q(ishtaruser__person__name__icontains=q) @@ -899,10 +897,8 @@ def autocomplete_user(request): def autocomplete_ishtaruser(request): - ishtaruser = getattr(request.user, "ishtaruser", None) - if not ishtaruser: - return HttpResponse("[]", content_type="text/plain") - if not ishtaruser.has_permission("ishtar_common.view_person"): + query = get_autocomplete_query(request, "ishtar_common", "view_person") + if query is None: return HttpResponse("[]", content_type="text/plain") q = request.GET.get("term", "") limit = request.GET.get("limit", 20) @@ -910,7 +906,6 @@ def autocomplete_ishtaruser(request): limit = int(limit) except ValueError: return HttpResponseBadRequest() - query = Q() for q in q.split(" "): qu = ( Q(person__name__unaccent__icontains=q) @@ -926,14 +921,8 @@ def autocomplete_ishtaruser(request): def autocomplete_person( request, person_types=None, attached_to=None, is_ishtar_user=None, permissive=False ): - ishtaruser = getattr(request.user, "ishtaruser", None) - if not ishtaruser: - return HttpResponse("[]", content_type="text/plain") - all_items = ishtaruser.has_permission("ishtar_common.view_person") - own_items = False - if not all_items: - own_items = ishtaruser.has_permission("ishtar_common.view_own_person") - if not all_items and not own_items or not request.GET.get("term"): + query = get_autocomplete_query(request, "ishtar_common", "view_person") + if query is None: return HttpResponse("[]", content_type="text/plain") q = request.GET.get("term") limit = request.GET.get("limit", 20) @@ -941,7 +930,6 @@ def autocomplete_person( limit = int(limit) except ValueError: return HttpResponseBadRequest() - query = Q() for q in q.split(" "): qu = ( Q(name__unaccent__icontains=q) @@ -964,10 +952,6 @@ def autocomplete_person( pass if is_ishtar_user: query = query & Q(ishtaruser__isnull=False) - if own_items: - if not hasattr(request.user, "ishtaruser"): - return HttpResponse(json.dumps([]), content_type="text/plain") - query &= models.Person.get_query_owns(request.user.ishtaruser) persons = models.Person.objects.filter(query).distinct()[:limit] data = json.dumps( [{"id": person.pk, "value": str(person)} for person in persons if person] @@ -976,14 +960,8 @@ def autocomplete_person( def autocomplete_import(request): - ishtaruser = getattr(request.user, "ishtaruser", None) - if not ishtaruser: - return HttpResponse("[]", content_type="text/plain") - all_items = ishtaruser.has_permission("ishtar_common.view_import") - own_items = False - if not all_items: - own_items = ishtaruser.has_permission("ishtar_common.view_own_import") - if not all_items and not own_items or not request.GET.get("term"): + query = get_autocomplete_query(request, "ishtar_common", "view_import") + if query is None: return HttpResponse("[]", content_type="text/plain") q = request.GET.get("term") limit = request.GET.get("limit", 20) @@ -991,14 +969,9 @@ def autocomplete_import(request): limit = int(limit) except ValueError: return HttpResponseBadRequest() - query = Q() for q in q.split(" "): query = query & (Q(name__unaccent__icontains=q) | Q(group__name__unaccent__icontains=q)) - if own_items: - if not hasattr(request.user, "ishtaruser"): - return HttpResponse(json.dumps([]), content_type="text/plain") - query &= models.Import.get_query_owns(request.user.ishtaruser) items = models.Import.objects.filter(query).distinct()[:limit] data = [{"id": item.pk, "value": item.name} for item in items if item] return HttpResponse(json.dumps(data), content_type="text/plain") @@ -1085,7 +1058,8 @@ def autocomplete_advanced_town(request, department_id=None, state_id=None): def autocomplete_document(request): - if not request.GET.get("term"): + query = get_autocomplete_query(request, "ishtar_common", "view_document") + if query is None: return HttpResponse(content_type="text/plain") q = request.GET.get("term") q = unicodedata.normalize("NFKD", q).encode("ascii", "ignore").decode() @@ -1097,12 +1071,11 @@ def autocomplete_document(request): "authors__person__cached_label__icontains", "authors_raw__icontains", ] - query = None for q in q.split(" "): qu = Q(**{fields[0]: q}) for field in fields[1:]: qu |= Q(**{field: q}) - query = qu if not query else query & qu + query = query & qu limit = 20 items = models.Document.objects.filter(query).exclude(title="").distinct()[:limit] data = json.dumps([{"id": item.pk, "value": str(item)} for item in items]) @@ -1128,18 +1101,10 @@ def department_by_state(request, state_id=""): def autocomplete_organization(request, orga_type=None): - ishtaruser = getattr(request.user, "ishtaruser", None) - if not ishtaruser: - return HttpResponse("[]", content_type="text/plain") - if ( - not ishtaruser.has_permission("ishtar_common.view_organization") - and not ishtaruser.has_permission("ishtar_common.view_own_organization") - ): - return HttpResponse("[]", content_type="text/plain") - if not request.GET.get("term"): + query = get_autocomplete_query(request, "ishtar_common", "view_organization") + if query is None: return HttpResponse("[]", content_type="text/plain") q = request.GET.get("term") - query = Q() for q in q.split(" "): extra = Q(cached_label__unaccent__icontains=q) query = query & extra @@ -1157,18 +1122,10 @@ def autocomplete_organization(request, orga_type=None): def autocomplete_author(request): - ishtaruser = getattr(request.user, "ishtaruser", None) - if not ishtaruser: - return HttpResponse("[]", content_type="text/plain") - if not ishtaruser.has_permission( - "ishtar_common.view_author" - ) and not ishtaruser.has_permission( - "ishtar_common.view_own_author"): - return HttpResponse("[]", content_type="text/plain") - if not request.GET.get("term"): + query = get_autocomplete_query(request, "ishtar_common", "view_author") + if query is None: return HttpResponse("[]", content_type="text/plain") q = request.GET.get("term") - query = Q() for q in q.split(" "): extra = ( Q(person__name__icontains=q) @@ -1184,10 +1141,8 @@ def autocomplete_author(request): def autocomplete_biographical_note(request): - ishtaruser = getattr(request.user, "ishtaruser", None) - if not ishtaruser: - return HttpResponse("[]", content_type="text/plain") - if not ishtaruser.has_permission("ishtar_common.view_person"): + query = get_autocomplete_query(request, "ishtar_common", "view_person") + if query is None: return HttpResponse("[]", content_type="text/plain") q = request.GET.get("term", "") limit = request.GET.get("limit", 20) @@ -1195,7 +1150,6 @@ def autocomplete_biographical_note(request): limit = int(limit) except ValueError: return HttpResponseBadRequest() - query = Q() for q in q.split(" "): qu = ( Q(last_name__unaccent__icontains=q) @@ -1251,13 +1205,47 @@ show_import = show_item(models.Import, "import") show_import_group = show_item(models.ImportGroup, "importgroup") +ACTION_MODEL_DICT = { + 'import': models.Import, + 'account': models.IshtarUser, + 'document': models.Document, + 'person': models.Person, + 'orga': models.Organization, + 'organization': models.Organization, + 'operation': apps.get_model("archaeological_operations", "Operation"), + 'administrativact': apps.get_model( + "archaeological_operations", "AdministrativeAct"), + 'file': apps.get_model("archaeological_files", "File"), + 'site': apps.get_model("archaeological_operations", "ArchaeologicalSite"), + 'record': apps.get_model("archaeological_context_records", "ContextRecord"), + 'find': apps.get_model("archaeological_finds", "Find"), + 'treatment': apps.get_model("archaeological_finds", "Treatment"), + 'treatmentfle': apps.get_model("archaeological_finds", "TreatmentFile"), + 'exhibition': apps.get_model("archaeological_finds", "Exhibition"), + 'container': apps.get_model("archaeological_warehouse", "Container"), + 'warehouse': apps.get_model("archaeological_warehouse", "Warehouse"), +} + + def action(request, action_slug, obj_id=None, *args, **kwargs): """ Action management """ - if not check_permission(request, action_slug, obj_id): + if not check_permission(request, action_slug): not_permitted_msg = ugettext("Operation not permitted.") - return HttpResponse(not_permitted_msg) + if obj_id: + model_name = action.split('_')[0].split("-")[0].split("/")[0] + if model_name not in ACTION_MODEL_DICT: + print(f"ishtar_common/views - action: {model_name} not in ACTION_MODEL_DICT") + return HttpResponse(not_permitted_msg) + try: + obj = ACTION_MODEL_DICT[model_name].objects.get(pk=obj_id) + except ACTION_MODEL_DICT[model_name].DoesNotExist: + return HttpResponse(not_permitted_msg) + if not check_permission(request, action_slug, obj): + return HttpResponse(not_permitted_msg) + else: + return HttpResponse(not_permitted_msg) request.session["CURRENT_ACTION"] = action_slug dct = {} globals_dct = globals() @@ -2845,7 +2833,7 @@ class DocumentEditView(DocumentFormMixin, UpdateView): document = models.Document.objects.get(pk=self.kwargs.get("pk")) except models.Document.DoesNotExist: raise Http404() - if not check_permission(self.request, "document/edit", document.pk): + if not check_permission(self.request, "ishtar_common.change_document", document): raise Http404() initial = {} for k in ( @@ -3571,7 +3559,7 @@ class GeoEditView(GeoFormMixin, UpdateView): except models.GeoVectorData.DoesNotExist: raise Http404() - if not check_permission(self.request, "geo/edit", geo.pk): + if not check_permission(self.request, "ishtar_common.change_geovectordata", geo): raise Http404() initial = {} diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 345bd0025..9f5755eaf 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -134,6 +134,23 @@ LIST_FIELDS = { # key: hierarchic depth HIERARCHIC_FIELDS = list(LIST_FIELDS.keys()) +def get_autocomplete_query(request, app, model_name): + ishtaruser = getattr(request.user, "ishtaruser", None) + if not ishtaruser or not request.GET.get("term"): + return + if ishtaruser.has_permission(f"{app}.view_{model_name}"): + return Q() + if not ishtaruser.has_permission(f"{app}.view_own_{model_name}"): + return + permission_id = Permission.objects.get(codename=f"view_own_{model_name}").id + object_ids = [ + int(pk) for pk in UserObjectPermission.objects.filter( + permission_id=permission_id, user_id=request.user.id + ).values_list("object_pk", flat=True) + ] + return Q(pk__in=object_ids) + + def get_autocomplete_queries(request, label_attributes, extra=None): if not label_attributes: return [Q(pk__isnull=True)] @@ -171,9 +188,17 @@ def get_autocomplete_item(model, extra=None): extra = {} def func(request, current_right=None, limit=20): + meta = model._meta + model_name = meta.model_name.lower() + if model_name == "basefind": + model_name = "find" + base_query = get_autocomplete_query(request, meta.app_label, model_name) + if base_query is None: + return HttpResponse(content_type="text/plain") result = OrderedDict() + base_query = model.objects.filter(base_query) for query in get_autocomplete_queries(request, ["cached_label"], extra=extra): - objects = model.objects.filter(query).values("cached_label", "id")[:limit] + objects = base_query.filter(query).values("cached_label", "id")[:limit] for obj in objects: if obj["id"] not in list(result.keys()): result[obj["id"]] = obj["cached_label"] @@ -190,15 +215,15 @@ def get_autocomplete_item(model, extra=None): return func -def check_permission(request, action_slug, obj_id=None): +def check_permission(request, action_slug, obj=None): main_menu = Menu(request.user) main_menu.init() if action_slug not in main_menu.items: # TODO return True - if obj_id: + if obj: return main_menu.items[action_slug].is_available( - request.user, obj_id + request.user, obj ) return main_menu.items[action_slug].can_be_available(request.user) @@ -253,12 +278,12 @@ def get_short_html_detail(model): def func(request, pk): model_name = model._meta.object_name not_permitted_msg = ugettext("Operation not permitted.") - if not check_permission(request, "view_" + model_name.lower(), pk): - return HttpResponse(not_permitted_msg) try: item = model.objects.get(pk=pk) except model.DoesNotExist: return HttpResponse(not_permitted_msg) + if not check_permission(request, "view_" + model_name.lower(), item): + return HttpResponse(not_permitted_msg) html = item.get_short_html_detail() return HttpResponse(html) @@ -270,15 +295,15 @@ def modify_qa_item(model, frm, callback=None): template = "ishtar/forms/qa_new_item.html" model_name = model._meta.object_name not_permitted_msg = ugettext("Operation not permitted.") - if not check_permission(request, "change_" + model_name.lower(), pk): - return HttpResponse(not_permitted_msg) - slug = model.SLUG - if model.SLUG == "site": - slug = "archaeologicalsite" try: item = model.objects.get(pk=pk) except model.DoesNotExist: return HttpResponse(not_permitted_msg) + if not check_permission(request, "change_" + model_name.lower(), item): + return HttpResponse(not_permitted_msg) + slug = model.SLUG + if model.SLUG == "site": + slug = "archaeologicalsite" url_slug = "modify-" + slug dct = { "page_name": str(_("Modify a %s" % model_name.lower())), |