diff options
Diffstat (limited to 'ishtar_common')
-rw-r--r-- | ishtar_common/backend.py | 4 | ||||
-rw-r--r-- | ishtar_common/context_processors.py | 2 | ||||
-rw-r--r-- | ishtar_common/forms.py | 7 | ||||
-rw-r--r-- | ishtar_common/forms_common.py | 14 | ||||
-rw-r--r-- | ishtar_common/ishtar_menu.py | 58 | ||||
-rw-r--r-- | ishtar_common/menu_base.py | 24 | ||||
-rw-r--r-- | ishtar_common/menus.py | 6 | ||||
-rw-r--r-- | ishtar_common/models.py | 141 | ||||
-rw-r--r-- | ishtar_common/models_common.py | 33 | ||||
-rw-r--r-- | ishtar_common/models_imports.py | 34 | ||||
-rw-r--r-- | ishtar_common/templatetags/window_header.py | 15 | ||||
-rw-r--r-- | ishtar_common/urls.py | 256 | ||||
-rw-r--r-- | ishtar_common/utils.py | 106 | ||||
-rw-r--r-- | ishtar_common/views.py | 190 | ||||
-rw-r--r-- | ishtar_common/views_item.py | 6 | ||||
-rw-r--r-- | ishtar_common/wizards.py | 19 |
16 files changed, 514 insertions, 401 deletions
diff --git a/ishtar_common/backend.py b/ishtar_common/backend.py index 00f90f444..c69a92d10 100644 --- a/ishtar_common/backend.py +++ b/ishtar_common/backend.py @@ -32,6 +32,7 @@ class ObjectPermBackend(ModelBackend): supports_object_permissions = True supports_anonymous_user = True + """ def has_perm(self, user_obj, perm, model=None, obj=None, session=None): if not user_obj.is_authenticated: return False @@ -48,7 +49,7 @@ class ObjectPermBackend(ModelBackend): is_ownperm = perm.split(".")[-1].split("_")[1] == "own" except IndexError: is_ownperm = False - if ishtar_user.has_right("administrator", session=session): + if ishtar_user.has_permission("ishtaradmin"): return True main_right = ishtar_user.person.has_right( perm, session=session @@ -65,3 +66,4 @@ class ObjectPermBackend(ModelBackend): return False return not is_ownperm or model.has_item_of(ishtar_user) return not is_ownperm or obj.is_own(user_obj) + """ diff --git a/ishtar_common/context_processors.py b/ishtar_common/context_processors.py index 74e38efc4..59d517192 100644 --- a/ishtar_common/context_processors.py +++ b/ishtar_common/context_processors.py @@ -181,7 +181,7 @@ def get_base_context(request): "search_model__app_label", "search_model__model" ).distinct() ] - if request.user.ishtaruser.has_right("administrator", session=request.session): + if request.user.ishtaruser.has_permission("ishtaradmin"): dct["ADMIN"] = True if ( request.user.ishtaruser.current_profile diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index ad76d63cd..e5ffeefb5 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -722,7 +722,7 @@ class IshtarForm(forms.Form, BSForm): if not any( True for permission in permissions - if ishtar_user.has_perm(permission) + if ishtar_user.has_permission(permission) ): continue for option, value in options.items(): @@ -1010,7 +1010,10 @@ class ImportSelect(HistorySelect): def __init__(self, *args, **kwargs): user = kwargs.get("user", None) super().__init__(*args, **kwargs) - if not user or (not user.has_perm("view_import") and not user.has_perm("view_own_import")): + ishtaruser = getattr(user, "ishtaruser", None) + if not ishtaruser or ( + not ishtaruser.has_permission("ishtar_common.view_import") + and not ishtaruser.has_permission("ishtar_common.view_own_import")): self.fields.pop("imports") diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index b1e4e7ef4..22e23f3ca 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -257,9 +257,13 @@ class BaseImportForm(IshtarForm, forms.ModelForm): self._post_init() def _filter_importer_type_query(self, q, user): - if user.is_superuser or user.ishtaruser.has_right("add_import"): + ishtaruser = getattr(user, "ishtaruser", None) + if not ishtaruser: + self.fields["importer_type"].choices = [("", "--")] + return + if user.is_superuser or ishtaruser.has_permission("ishtar_common.add_import"): return q - if not user.ishtaruser.has_right("add_own_import"): + if not user.ishtaruser.has_permission("ishtar_common.add_own_import"): self.fields["importer_type"].choices = [("", "--")] return q = q.filter(users__pk=user.ishtaruser.pk) @@ -555,10 +559,12 @@ class TargetKeyForm(forms.ModelForm): self.associated_import = None if instance and instance.pk: model = instance.target.associated_model + ishtaruser = getattr(self.user, "ishtaruser", None) + meta = model._meta if ( model - and self.user.has_perm( - "{}.change_{}".format(model._meta.app_label, model._meta.model_name) + and ishtaruser.has_permission( + f"{meta.app_label}.change_{meta.model_name}" ) and hasattr(model, "admin_url") ): diff --git a/ishtar_common/ishtar_menu.py b/ishtar_common/ishtar_menu.py index 5c2d1bdb1..aa8ed3b8f 100644 --- a/ishtar_common/ishtar_menu.py +++ b/ishtar_common/ishtar_menu.py @@ -23,7 +23,7 @@ from ishtar_common.menu_base import SectionItem, MenuItem from . import models -# be careful: each access_controls must be relevant with check_rights in urls +# be careful: each access_controls must be relevant with check_permissions in urls MENU_SECTIONS = [ (1, SectionItem("home", _("Home"), childs=[])), @@ -41,37 +41,39 @@ MENU_SECTIONS = [ "person_search", _("Search"), model=models.Person, - access_controls=["add_person"], + access_controls=["ishtar_common.add_person"], ), MenuItem( "person_creation", _("Creation"), model=models.Person, - access_controls=["add_person"], + access_controls=["ishtar_common.add_person"], ), MenuItem( "person_modification", _("Modification"), model=models.Person, - access_controls=["change_person", "change_own_person"], + access_controls=["ishtar_common.change_person", + "ishtar_common.change_own_person"], ), MenuItem( "person-merge", _("Automatic merge"), model=models.Person, - access_controls=["administrator"], + access_controls=["ishtaradmin"], ), MenuItem( "person-manual-merge", _("Manual merge"), model=models.Person, - access_controls=["administrator"], + access_controls=["ishtaradmin"], ), MenuItem( "person_deletion", _("Deletion"), model=models.Person, - access_controls=["change_person", "change_own_person"], + access_controls=["ishtar_common.change_person", + "ishtar_common.change_own_person"], ), ], ), @@ -84,7 +86,7 @@ MENU_SECTIONS = [ _("Addition/modification"), model=models.IshtarUser, access_controls=[ - "administrator", + "ishtaradmin", ], ), MenuItem( @@ -92,7 +94,7 @@ MENU_SECTIONS = [ _("Deletion"), model=models.IshtarUser, access_controls=[ - "administrator", + "ishtaradmin", ], ), ], @@ -106,8 +108,8 @@ MENU_SECTIONS = [ _("Search"), model=models.Organization, access_controls=[ - "add_organization", - "add_own_organization", + "ishtar_common.add_organization", + "ishtar_common.add_own_organization", ], ), MenuItem( @@ -115,8 +117,8 @@ MENU_SECTIONS = [ _("Creation"), model=models.Organization, access_controls=[ - "add_organization", - "add_own_organization", + "ishtar_common.add_organization", + "ishtar_common.add_own_organization", ], ), MenuItem( @@ -124,29 +126,29 @@ MENU_SECTIONS = [ _("Modification"), model=models.Organization, access_controls=[ - "change_organization", - "change_own_organization", + "ishtar_common.change_organization", + "ishtar_common.change_own_organization", ], ), MenuItem( "organization-merge", _("Automatic merge"), model=models.Organization, - access_controls=["administrator"], + access_controls=["ishtaradmin"], ), MenuItem( "orga-manual-merge", _("Manual merge"), model=models.Organization, - access_controls=["administrator"], + access_controls=["ishtaradmin"], ), MenuItem( "organization_deletion", _("Deletion"), model=models.Organization, access_controls=[ - "change_organization", - "change_own_organization", + "ishtar_common.change_organization", + "ishtar_common.change_own_organization", ], ), ], @@ -164,13 +166,15 @@ MENU_SECTIONS = [ "import-list", _("Current imports"), model=models.Import, - access_controls=["view_import", "change_import"], + access_controls=["ishtar_common.view_import", + "ishtar_common.change_import"], ), MenuItem( "import-list-old", _("Old imports"), model=models.Import, - access_controls=["view_import", "change_import"], + access_controls=["ishtar_common.view_import", + "ishtar_common.change_import"], ), ], ), @@ -185,25 +189,29 @@ MENU_SECTIONS = [ "document/search", _("Search"), model=models.Document, - access_controls=["view_document", "view_own_document"], + access_controls=["ishtar_common.view_document", + "ishtar_common.view_own_document"], ), MenuItem( "document/create", _("Creation"), model=models.Document, - access_controls=["add_document", "add_own_document"], + access_controls=["ishtar_common.add_document", + "ishtar_common.add_own_document"], ), MenuItem( "document/edit", _("Modification"), model=models.Document, - access_controls=["change_document", "change_own_document"], + access_controls=["ishtar_common.change_document", + "ishtar_common.change_own_document"], ), MenuItem( "document/delete", _("Deletion"), model=models.Document, - access_controls=["change_document", "change_own_document"], + access_controls=["ishtar_common.change_document", + "ishtar_common.change_own_document"], ), ], ), diff --git a/ishtar_common/menu_base.py b/ishtar_common/menu_base.py index e8470787a..e0f206a57 100644 --- a/ishtar_common/menu_base.py +++ b/ishtar_common/menu_base.py @@ -43,28 +43,28 @@ class SectionItem: return False return True - def can_be_available(self, user, session=None): + def can_be_available(self, user): if not self.check_profile_restriction(): return False if not self.childs: return True for child in self.childs: - if child.can_be_available(user, session=session): + if child.can_be_available(user): return True return False - def is_available(self, user, obj=None, session=None): + def is_available(self, user, obj=None): if not self.childs: return True for child in self.childs: - if child.is_available(user, obj, session=session): + if child.is_available(user, obj): return True return False def set_items(self, user, items, current_action=None, session=None): selected = None if user: - self.available = self.can_be_available(user, session=session) + self.available = self.can_be_available(user) for child in self.childs: selected = ( child.set_items(user, items, current_action, session=session) @@ -101,35 +101,37 @@ class MenuItem: return False return True - def can_be_available(self, user, session=None): + def can_be_available(self, user): if not self.check_profile_restriction(): return False if not self.access_controls: return True if not hasattr(user, "ishtaruser"): return False + ishtaruser = user.ishtaruser for access_control in self.access_controls: # check by profile - if user.ishtaruser.person.has_right(access_control, session=session): + if ishtaruser.has_permission(access_control): return True return False - def is_available(self, user, obj=None, session=None): + def is_available(self, user, obj=None): if not self.check_profile_restriction(): return False if not self.access_controls: return True if not hasattr(user, "ishtaruser"): return False + ishtaruser = user.ishtaruser for access_control in self.access_controls: - if user.ishtaruser.person.has_right( - access_control, obj=obj, session=session + if ishtaruser.has_permission( + access_control, obj=obj ): return True return False def set_items(self, user, items, current_action=None, session=None): if user: - self.available = self.can_be_available(user, session=session) + self.available = self.can_be_available(user) if self.idx == current_action: return True diff --git a/ishtar_common/menus.py b/ishtar_common/menus.py index b167c1765..aae127a09 100644 --- a/ishtar_common/menus.py +++ b/ishtar_common/menus.py @@ -135,20 +135,20 @@ class Menu: self.items_by_idx = {} childs = deepcopy(self.ref_childs) for idx, main_menu in enumerate(reversed(childs)): - if not main_menu.can_be_available(self.user, self.session): + if not main_menu.can_be_available(self.user): childs.pop(len(self.ref_childs) - idx - 1) continue self.items_by_idx[main_menu.idx] = main_menu sub_childs = main_menu.childs[:] for s_idx, child in enumerate(reversed(main_menu.childs)): - if not child.can_be_available(self.user, self.session): + if not child.can_be_available(self.user): sub_childs.pop(len(main_menu.childs) - s_idx - 1) continue self.items_by_idx[child.idx] = child if hasattr(child, "childs"): sub_sub_childs = child.childs[:] for ss_idx, subchild in enumerate(reversed(child.childs)): - if not subchild.can_be_available(self.user, self.session): + if not subchild.can_be_available(self.user): sub_sub_childs.pop(len(child.childs) - ss_idx - 1) continue self.items_by_idx[subchild.idx] = subchild diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 5f57e8398..b1f226088 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -2665,7 +2665,7 @@ class Organization(Address, Merge, OwnPerms, BaseGenderedType, ValueGetter, Main icon_class="fa fa-pencil", text=_("Bulk update"), target="many", - rights=["change_organization"], + rights=["ishtar_common.change_organization"], ) QUICK_ACTIONS = [QA_EDIT] @@ -2946,7 +2946,7 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem): icon_class="fa fa-pencil", text=_("Bulk update"), target="many", - rights=["change_person"], + rights=["ishtar_common.change_person"], ) QUICK_ACTIONS = [QA_EDIT] @@ -3130,72 +3130,6 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem): def is_natural(self): return not self.attached_to - def has_right(self, right_name, session=None, obj=None): - if "." in right_name: - right_name = right_name.split(".")[-1] - res, cache_key = "", "" - if session: - cache_key = "session-{}-{}".format(session.session_key, right_name) - res = cache.get(cache_key) - if res in (True, False): - return res - # list all cache key in order to clean them on profile change - cache_key_list = "sessionlist-{}".format(session.session_key) - key_list = cache.get(cache_key_list, []) - key_list.append(cache_key) - cache.set(cache_key_list, key_list, settings.CACHE_TIMEOUT) - if isinstance(right_name, (list, tuple)): - res = ( - bool( - self.profiles.filter( - current=True, profile_type__txt_idx__in=right_name - ).count() - ) - or bool( - self.profiles.filter( - current=True, - profile_type__groups__permissions__codename__in=right_name, - ).count() - ) - or bool( - self.ishtaruser.user_ptr.groups.filter( - permissions__codename__in=right_name - ).count() - ) - or bool( - self.ishtaruser.user_ptr.user_permissions.filter( - codename__in=right_name - ).count() - ) - ) - else: - res = ( - bool( - self.profiles.filter( - current=True, profile_type__txt_idx=right_name - ).count() - ) - or bool( - self.profiles.filter( - current=True, - profile_type__groups__permissions__codename=right_name, - ).count() - ) - or bool( - self.ishtaruser.user_ptr.groups.filter( - permissions__codename__in=[right_name] - ).count() - ) - or bool( - self.ishtaruser.user_ptr.user_permissions.filter( - codename__in=[right_name] - ).count() - ) - ) - if session: - cache.set(cache_key, res, settings.CACHE_TIMEOUT) - return res - def full_label(self): values = [] if self.title: @@ -3330,7 +3264,8 @@ class BiographicalNote(BaseHistorizedItem, ValueGetter, MainItem): url="biographicalnote-qa-edit", icon_class="fa fa-pencil", text=_("Edit biographical note"), - rights=["change_biographicalnote", "change_own_biographicalnote"], + rights=["ishtar_common.change_biographicalnote", + "ishtar_common.change_own_biographicalnote"], ) class Meta: @@ -3367,7 +3302,8 @@ class BiographicalNote(BaseHistorizedItem, ValueGetter, MainItem): return res def set_slug(self): - self.slug = create_slug(self.__class__, self.denomination, max_length=250, pk=self.pk) + self.slug = create_slug(self.__class__, self.denomination, max_length=250, + pk=self.pk) def get_extra_actions(self, request): """ @@ -3375,7 +3311,7 @@ class BiographicalNote(BaseHistorizedItem, ValueGetter, MainItem): """ # url, base_text, icon, extra_text, extra css class, is a quick action, actions = super().get_extra_actions(request) - can_edit = self.can_do(request, "change_biographicalnote") + can_edit = self.can_do(request, "ishtar_common.change_biographicalnote") if not can_edit: return actions actions += [ @@ -3823,11 +3759,54 @@ class IshtarUser(FullSearch): ) return cls.objects.create(user_ptr=user, person=person) - def has_right(self, right_name, session=None): - return self.person.has_right(right_name, session=session) - - def has_perm(self, perm, model=None, session=None, obj=None): - return self.person.has_right(perm, session=session, obj=None) + @property + def is_ishtaradmin(self): + is_ishtaradmin = getattr(self, "_is_ishtaradmin", None) + if is_ishtaradmin is not None: + return is_ishtaradmin + self._is_ishtaradmin = bool( + self.person.profiles.filter( + current=True, profile_type__txt_idx="administrator" + ).exists() + ) + return self._is_ishtaradmin + + def has_permission(self, permission, obj=None): + if permission == "ishtaradmin": + return self.is_ishtaradmin + if "." not in permission: + # TODO: perm delete + print(permission) + raise + if obj: + return self.user_ptr.has_perm(permission, obj) + return self.user_ptr.has_perm(permission) + """ + res = ( + bool( + self.profiles.filter( + current=True, profile_type__txt_idx=permission + ).count() + ) + or bool( + self.profiles.filter( + current=True, + profile_type__groups__permissions__codename=permission, + ).count() + ) + or bool( + self.ishtaruser.user_ptr.groups.filter( + permissions__codename__in=[permission] + ).count() + ) + or bool( + self.ishtaruser.user_ptr.user_permissions.filter( + codename__in=[permission] + ).count() + ) + ) + return res + """ def full_label(self): return self.person.full_label() @@ -4557,7 +4536,7 @@ class Document( icon_class="fa fa-pencil", text=_("Bulk update"), target="many", - rights=["change_document", "change_own_document"], + rights=["ishtar_common.change_document", "ishtar_common.change_own_document"], ) QUICK_ACTIONS = [ QA_EDIT, @@ -4566,14 +4545,14 @@ class Document( icon_class="fa fa-clone", text=_("Duplicate"), target="one", - rights=["change_document", "change_own_document"], + rights=["ishtar_common.change_document", "ishtar_common.change_own_document"], ), QuickAction( url="document-qa-packaging", icon_class="fa fa-gift", text=_("Packaging"), target="many", - rights=["change_document", "change_own_document"], + rights=["ishtar_common.change_document", "ishtar_common.change_own_document"], module="warehouse", ), ] @@ -4937,7 +4916,7 @@ class Document( actions = super(Document, self).get_extra_actions(request) # is_locked = self.is_locked(request.user) - can_edit_document = self.can_do(request, "change_document") + can_edit_document = self.can_do(request, "ishtar_common.change_document") if not can_edit_document: return actions actions += [ @@ -4961,7 +4940,7 @@ class Document( True, ) ) - can_create_document = self.can_do(request, "add_document") + can_create_document = self.can_do(request, "ishtar_common.add_document") if can_create_document: actions += [ ( diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py index 6f995569c..4a266af9c 100644 --- a/ishtar_common/models_common.py +++ b/ishtar_common/models_common.py @@ -1182,13 +1182,17 @@ class Imported(models.Model): abstract = True def _get_imports(self, user, key, limit): - if not user.ishtaruser: + ishtaruser = getattr(user, "ishtaruser", None) + if not ishtaruser: return [] q = getattr(self, key) - if user.is_superuser or user.ishtaruser.has_right("view_import"): + if ishtaruser.has_permission("ishtaradmin") or \ + ishtaruser.has_permission("ishtar_common.view_import"): q = q.all() - elif user.ishtaruser.has_right("view_own_import"): - q = q.filter(Q(user=user.ishtaruser) | Q(importer_type__users__pk=user.ishtaruser.pk)) + elif ishtaruser.has_permission("ishtar_common.view_own_import"): + q = q.filter(Q(user=user.ishtaruser) | Q( + importer_type__users__pk=user.ishtaruser.pk) + ) else: return [] q = q.order_by("-id") @@ -1946,7 +1950,8 @@ class DocumentItem: @property def pdf_attached(self): for document in self.documents.filter( - Q(associated_file__isnull=False) | Q(source__associated_file__isnull=False) + Q(associated_file__isnull=False) | + Q(source__associated_file__isnull=False) ).all(): return document.pdf_attached @@ -1967,7 +1972,7 @@ class DocumentItem: print(f"**WARNING** can_do not implemented for {self.__class__}") return actions - can_add_doc = self.can_do(request, "add_document") + can_add_doc = self.can_do(request, "ishtar_common.add_document") if can_add_doc and ( not hasattr(self, "is_locked") or not self.is_locked(request.user) ): @@ -3318,13 +3323,13 @@ class MainItem(ShortMenuItem, SerializeItem, SheetItem): pass @classmethod - def get_quick_actions(cls, user, session=None, obj=None): + def get_quick_actions(cls, user): """ Get a list of (url, title, icon, target) actions for an user """ qas = [] for action in cls.QUICK_ACTIONS: - if not action.is_available(user, session=session, obj=obj): + if not action.is_available(user): continue qas.append( [ @@ -3376,14 +3381,14 @@ class MainItem(ShortMenuItem, SerializeItem, SheetItem): """ Check permission availability for the current object. :param request: request object - :param action_name: action name eg: "change_find" + :param action_name: action name eg: "archaeological_finds.change_find" :return: boolean """ # overload with OwnPerm when _own_ is relevant if not getattr(request.user, "ishtaruser", None): return False user = request.user - return user.ishtaruser.has_right(action_name, request.session) + return user.ishtaruser.has_permission(action_name) def get_extra_actions(self, request): if not hasattr(self, "SLUG"): @@ -3636,7 +3641,9 @@ class Town(GeographicItem, Imported, DocumentItem, MainItem, models.Model): # url, base_text, icon, extra_text, extra css class, is a quick action actions = super().get_extra_actions(request) profile = get_current_profile() - can_add_geo = profile.mapping and self.can_do(request, "add_geovectordata") + can_add_geo = profile.mapping and self.can_do( + request, "ishtar_common.add_geovectordata" + ) if can_add_geo: actions.append(self.get_add_geo_action()) return actions @@ -4168,7 +4175,7 @@ class QuickAction: if self.target not in ("one", "many", None): raise AttributeError("target must be one, many or None") - def is_available(self, user, session=None, obj=None): + def is_available(self, user, obj=None): if self.module and not getattr(get_current_profile(), self.module): return False if not self.rights: # no restriction @@ -4178,7 +4185,7 @@ class QuickAction: user = user.ishtaruser for right in self.rights: - if user.has_perm(right, session=session, obj=obj): + if user.has_permission(right, obj=obj): return True return False diff --git a/ishtar_common/models_imports.py b/ishtar_common/models_imports.py index 5e29b98ed..ddb23e490 100644 --- a/ishtar_common/models_imports.py +++ b/ishtar_common/models_imports.py @@ -1447,25 +1447,28 @@ class BaseImport(models.Model, OwnPerms, SheetItem): abstract = True @classmethod - def get_permissions_for_actions(cls, user, session): + def get_permissions_for_actions(cls, user): if not hasattr(user, "ishtaruser") or not user.ishtaruser: return False, False, False, False - can_edit_all, can_delete_all, can_edit_own, can_delete_own = False, False, False, False - if user.is_superuser: + can_edit_all, can_delete_all = False, False + can_edit_own, can_delete_own = False, False + ishtaruser = user.ishtaruser + if ishtaruser.has_permission("ishtaradmin"): can_edit_all = True can_delete_all = True - if user.ishtaruser.has_right("change_import", session=session): - can_edit_all = True - elif user.ishtaruser.has_right("change_own_import", session=session): - can_edit_own = True - if user.ishtaruser.has_right("delete_import", session=session): - can_delete_all = True - elif user.ishtaruser.has_right("delete_own_import", session=session): - can_delete_own = True + else: + if ishtaruser.has_permission("ishtar_common.change_import"): + can_edit_all = True + elif ishtaruser.has_permission("ishtar_common.change_own_import"): + can_edit_own = True + if ishtaruser.has_permission("ishtar_common.delete_import"): + can_delete_all = True + elif ishtaruser.has_permission("ishtar_common.delete_own_import"): + can_delete_own = True return can_edit_all, can_delete_all, can_edit_own, can_delete_own @classmethod - def query_can_access(cls, user, perm="view_import"): + def query_can_access(cls, user, perm="ishtar_common.view_import"): """ Filter the query to check access permissions :param user: User instance @@ -1474,8 +1477,11 @@ class BaseImport(models.Model, OwnPerms, SheetItem): q = cls.objects if not isinstance(perm, (list, tuple)): perm = [perm] - if user.is_superuser or (hasattr(user, "ishtaruser") and user.ishtaruser and - any(user.ishtaruser.has_right(p) for p in perm)): + ishtaruser = getattr(user, "ishtaruser", None) + if not ishtaruser: + return q.filter(pk__isnull=True) + if ishtaruser.has_permission("ishtaradmin") or ( + any(ishtaruser.has_permission(p) for p in perm)): return q q = q.filter(Q(importer_type__users__pk=user.ishtaruser.pk)) return q diff --git a/ishtar_common/templatetags/window_header.py b/ishtar_common/templatetags/window_header.py index bfcd95883..23d779944 100644 --- a/ishtar_common/templatetags/window_header.py +++ b/ishtar_common/templatetags/window_header.py @@ -19,7 +19,9 @@ def window_nav(context, item, window_id, show_url, modify_url='', histo_url='', extra_actions = [] if hasattr(item, 'get_extra_actions'): try: - extra_actions = item.get_extra_actions(context['request'], context["window_id_underscore"]) + extra_actions = item.get_extra_actions( + context['request'], context["window_id_underscore"] + ) except (KeyError, TypeError): extra_actions = item.get_extra_actions(context['request']) extra_actions = sorted_actions(extra_actions) @@ -27,14 +29,8 @@ def window_nav(context, item, window_id, show_url, modify_url='', histo_url='', if hasattr(item, 'get_extra_templates'): extra_templates = item.get_extra_templates(context['request']) - slug = None - if hasattr(item, "LONG_SLUG"): - slug = item.LONG_SLUG - elif hasattr(item, "SLUG"): - slug = item.SLUG modify_url_value, delete_url = None, None - can_edit = hasattr(item, 'can_do') and slug and \ - item.can_do(context['request'], 'change_' + slug) + can_edit = hasattr(item, 'can_edit') and item.can_edit(context['request']) if can_edit: modify_url_value = modify_url delete_url = getattr(item, "DELETE_URL", False) @@ -81,8 +77,7 @@ def window_file_nav(context, item, window_id, previous=None, nxt=None): revert_url = 'revert-file' add_operation = "" modify_url_value, delete_url = None, None - can_edit = hasattr(item, 'can_do') and \ - item.can_do(context['request'], 'change_file') + can_edit = hasattr(item, 'can_edit') and item.can_edit(context['request']) if can_edit: modify_url_value = modify_url delete_url = getattr(item, "DELETE_URL", False) diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py index a205e3b01..8bb8dd356 100644 --- a/ishtar_common/urls.py +++ b/ishtar_common/urls.py @@ -26,9 +26,9 @@ from django.views.generic import TemplateView from .menus import Menu from ishtar_common import views, models, views_item -from ishtar_common.utils import check_rights, get_urls_for_model +from ishtar_common.utils import check_permissions, get_urls_for_model -# be careful: each check_rights must be relevant with ishtar_menu +# be careful: each check_permissions must be relevant with ishtar_menu # forms urlpatterns = [ @@ -69,72 +69,76 @@ urlpatterns = [ ), url( r"person_search/(?P<step>.+)?$", - check_rights(["add_person"])(views.person_search_wizard), + check_permissions(["ishtar_common.add_person"])(views.person_search_wizard), name="person_search", ), url( r"person_creation/(?P<step>.+)?$", - check_rights(["add_person"])(views.person_creation_wizard), + check_permissions(["ishtar_common.add_person"])(views.person_creation_wizard), name="person_creation", ), url( r"person_modification/(?P<step>.+)?$", - check_rights(["change_person", "change_own_person"])( - views.person_modification_wizard - ), + check_permissions( + ["ishtar_common.change_person", "ishtar_common.change_own_person"] + )(views.person_modification_wizard), name="person_modification", ), url(r"person_modify/(?P<pk>.+)/$", views.person_modify, name="person_modify"), url( r"person_deletion/(?P<step>.+)?$", - check_rights(["change_person", "change_own_person"])( - views.person_deletion_wizard - ), + check_permissions( + ["ishtar_common.change_person", "ishtar_common.change_own_person"] + )(views.person_deletion_wizard), name="person_deletion", ), url(r"person_delete/(?P<pk>.+)/$", views.person_delete, name="person_delete"), url( r"^person-edit/$", - check_rights(["add_person"])(views.PersonCreate.as_view()), + check_permissions(["ishtar_common.add_person"])(views.PersonCreate.as_view()), name="person_create", ), url( r"^person-edit/(?P<pk>\d+)$", - check_rights(["change_person", "change_own_person"])( - views.PersonEdit.as_view() - ), + check_permissions( + ["ishtar_common.change_person", "ishtar_common.change_own_person"] + )(views.PersonEdit.as_view()), name="person_edit", ), url( r"^person-qa-bulk-update/(?P<pks>[0-9-]+)?/$", - check_rights(["change_person", "change_own_person"])( - views.QAPersonForm.as_view() - ), + check_permissions( + ["ishtar_common.change_person", "ishtar_common.change_own_person"] + )(views.QAPersonForm.as_view()), name="person-qa-bulk-update", ), url( r"^person-qa-bulk-update/(?P<pks>[0-9-]+)?/confirm/$", - check_rights(["change_person", "change_own_person"])( - views.QAPersonForm.as_view() - ), + check_permissions( + ["ishtar_common.change_person", "ishtar_common.change_own_person"] + )(views.QAPersonForm.as_view()), name="person-qa-bulk-update-confirm", kwargs={"confirm": True}, ), url( r"organization_search/(?P<step>.+)?$", - check_rights(["add_organization"])(views.organization_search_wizard), + check_permissions( + ["ishtar_common.add_organization"] + )(views.organization_search_wizard), name="organization_search", ), url( r"organization_creation/(?P<step>.+)?$", - check_rights(["add_organization"])(views.organization_creation_wizard), + check_permissions( + ["ishtar_common.add_organization"] + )(views.organization_creation_wizard), name="organization_creation", ), url( r"organization_modification/(?P<step>.+)?$", - check_rights(["change_organization", "change_own_organization"])( - views.organization_modification_wizard - ), + check_permissions( + ["ishtar_common.change_organization", "ishtar_common.change_own_organization"] + )(views.organization_modification_wizard), name="organization_modification", ), url( @@ -144,9 +148,9 @@ urlpatterns = [ ), url( r"organization_deletion/(?P<step>.+)?$", - check_rights(["change_organization", "change_own_organization"])( - views.organization_deletion_wizard - ), + check_permissions( + ["ishtar_common.change_organization", "ishtar_common.change_own_organization"] + )(views.organization_deletion_wizard), name="organization_deletion", ), url( @@ -156,47 +160,54 @@ urlpatterns = [ ), url( r"organization-edit/$", - check_rights(["add_organization"])(views.OrganizationCreate.as_view()), + check_permissions( + ["ishtar_common.add_organization"] + )(views.OrganizationCreate.as_view()), name="organization_create", ), url( r"organization-edit/(?P<pk>\d+)$", - check_rights(["change_organization", "change_own_organization"])( - views.OrganizationEdit.as_view() - ), + check_permissions( + ["ishtar_common.change_organization", + "ishtar_common.change_own_organization"] + )(views.OrganizationEdit.as_view()), name="organization_edit", ), url( r"organization-person-edit/$", - check_rights(["add_organization"])(views.OrganizationPersonCreate.as_view()), + check_permissions( + ["ishtar_common.add_organization"] + )(views.OrganizationPersonCreate.as_view()), name="organization_person_create", ), url( r"organization-person-edit/(?P<pk>\d+)$", - check_rights(["change_organization", "change_own_organization"])( - views.OrganizationPersonEdit.as_view() - ), + check_permissions( + ["ishtar_common.change_organization", "ishtar_common.change_own_organization"] + )(views.OrganizationPersonEdit.as_view()), name="organization_person_edit", ), url( r"^organization-qa-bulk-update/(?P<pks>[0-9-]+)?/$", - check_rights(["change_organization", "change_own_organization"])( - views.QAOrganizationForm.as_view() - ), + check_permissions( + ["ishtar_common.change_organization", "ishtar_common.change_own_organization"] + )(views.QAOrganizationForm.as_view()), name="organization-qa-bulk-update", ), url( r"^organization-qa-bulk-update/(?P<pks>[0-9-]+)?/confirm/$", - check_rights(["change_organization", "change_own_organization"])( - views.QAOrganizationForm.as_view() - ), + check_permissions( + ["ishtar_common.change_organization", "ishtar_common.change_own_organization"] + )(views.QAOrganizationForm.as_view()), name="organization-qa-bulk-update-confirm", kwargs={"confirm": True}, ), url(r"get-ishtaruser/(?P<type>.+)?$", views.get_ishtaruser, name="get-ishtaruser"), url( r"account_management/(?P<step>.+)?$", - check_rights(["add_ishtaruser"])(views.account_management_wizard), + check_permissions( + ["ishtar_common.add_ishtaruser"] + )(views.account_management_wizard), name="account_management", ), url( @@ -206,67 +217,97 @@ urlpatterns = [ ), url( r"account_deletion/(?P<step>.+)?$", - check_rights(["add_ishtaruser"])(views.account_deletion_wizard), + check_permissions( + ["ishtar_common.add_ishtaruser"] + )(views.account_deletion_wizard), name="account_deletion", ), url( r"^import-new/$", - check_rights(["add_import", "add_own_import"])(views.NewImportView.as_view()), + check_permissions( + ["ishtar_common.add_import", "ishtar_common.add_own_import"] + )(views.NewImportView.as_view()), name="new_import", ), url( r"^import-edit/(?P<pk>[0-9]+)/$", - check_rights(["change_import", "change_own_import"])(views.EditImportView.as_view()), + check_permissions( + ["ishtar_common.change_import", "ishtar_common.change_own_import"] + )(views.EditImportView.as_view()), name="edit_import", ), url( r"^import-new-gis/$", - check_rights(["add_import", "add_own_import"])(views.NewImportGISView.as_view()), + check_permissions( + ["ishtar_common.add_import", "ishtar_common.add_own_import"] + )(views.NewImportGISView.as_view()), name="new_import_gis", ), url( r"^import-new-group/$", - check_rights(["add_import", "add_own_import"])(views.NewImportGroupView.as_view()), + check_permissions( + ["ishtar_common.add_import", "ishtar_common.add_own_import"] + )(views.NewImportGroupView.as_view()), name="new_import_group", ), url( r"^import-list/$", - check_rights(["view_import", "change_import", "change_own_import"])(views.ImportListView.as_view()), + check_permissions( + ["ishtar_common.view_import", "ishtar_common.change_import", + "ishtar_common.change_own_import"] + )(views.ImportListView.as_view()), name="current_imports", ), url( r"^import-list-table/$", - check_rights(["view_import", "change_import", "change_own_import"])(views.ImportListTableView.as_view()), + check_permissions( + ["ishtar_common.view_import", "ishtar_common.change_import", + "ishtar_common.change_own_import"] + )(views.ImportListTableView.as_view()), name="current_imports_table", ), url( r"^import-get-status/$", - check_rights(["view_import", "change_import", "change_own_import"])(views.import_get_status), - name="import_get_status", + check_permissions( + ["ishtar_common.view_import", "ishtar_common.change_import", + "ishtar_common.change_own_import"] + )(views.import_get_status), + name="import_get_status", ), url( r"^import-list-old/$", - check_rights(["view_import", "change_import", "change_own_import"])(views.ImportOldListView.as_view()), + check_permissions( + ["ishtar_common.view_import", "ishtar_common.change_import", + "ishtar_common.change_own_import"] + )(views.ImportOldListView.as_view()), name="old_imports", ), url( r"^import-delete/(?P<pk>[0-9]+)/$", - check_rights(["delete_import", "delete_own_import"])(views.ImportDeleteView.as_view()), + check_permissions( + ["ishtar_common.delete_import", "ishtar_common.delete_own_import"] + )(views.ImportDeleteView.as_view()), name="import_delete", ), url( r"^import-group-delete/(?P<pk>[0-9]+)/$", - check_rights(["delete_import", "delete_own_import"])(views.ImportGroupDeleteView.as_view()), + check_permissions( + ["ishtar_common.delete_import", "ishtar_common.delete_own_import"] + )(views.ImportGroupDeleteView.as_view()), name="import_group_delete", ), url( r"^import-link-unmatched/(?P<pk>[0-9]+)/$", - check_rights(["change_import", "change_own_import"])(views.ImportMatchView.as_view()), + check_permissions( + ["ishtar_common.change_import", "ishtar_common.change_own_import"] + )(views.ImportMatchView.as_view()), name="import_link_unmatched", ), url( r"^import-csv-view/(?P<target>source|result|match|error)/(?P<group>group\-)?(?P<pk>[0-9]+)/$", - check_rights(["view_import", "view_own_import"])(views.ImportCSVView.as_view()), + check_permissions( + ["ishtar_common.view_import", "ishtar_common.view_own_import"] + )(views.ImportCSVView.as_view()), name="import_display_csv", ), url( @@ -282,12 +323,16 @@ urlpatterns = [ ), url( r"^import-pre-form/(?P<import_id>[0-9]+)/$", - check_rights(["change_import", "change_own_import"])(views.ImportPreFormView.as_view()), + check_permissions( + ["ishtar_common.change_import", "ishtar_common.change_own_import"] + )(views.ImportPreFormView.as_view()), name="import_pre_import_form", ), url( r"^import-ignore-line/(?P<line_id>[0-9]+)/$", - check_rights(["change_import", "change_own_import"])(views.line_error), + check_permissions( + ["ishtar_common.change_import", "ishtar_common.change_own_import"] + )(views.line_error), name="import_ignore_line", ), url(r"^profile(?:/(?P<pk>[0-9]+))?/$", views.ProfileEdit.as_view(), name="profile"), @@ -417,9 +462,10 @@ urlpatterns += [ ), url( r"^biographicalnote-qa-edit/(?P<pks>[0-9-]+)?/$", - check_rights(["change_biographicalnote", "change_own_biographicalnote"])( - views.QABiographicalNoteForm.as_view() - ), + check_permissions( + ["ishtar_common.change_biographicalnote", + "ishtar_common.change_own_biographicalnote"] + )(views.QABiographicalNoteForm.as_view()), name="biographicalnote-qa-edit", ), url( @@ -551,44 +597,44 @@ urlpatterns += [ ), url( r"document/search/(?P<step>.+)?$", - check_rights(["view_document", "view_own_document"])( - views.document_search_wizard - ), + check_permissions( + ["ishtar_common.view_document", "ishtar_common.view_own_document"] + )(views.document_search_wizard), name="search-document", ), url( r"document/search/(?P<step>.+)?$", - check_rights(["view_document", "view_own_document"])( - views.document_search_wizard - ), + check_permissions( + ["ishtar_common.view_document", "ishtar_common.view_own_document"] + )(views.document_search_wizard), name="document_search", ), url( r"document/create/$", - check_rights(["add_document", "add_own_document"])( - views.DocumentCreateView.as_view() - ), + check_permissions( + ["ishtar_common.add_document", "ishtar_common.add_own_document"] + )(views.DocumentCreateView.as_view()), name="create-document", ), url( r"document/edit/$", - check_rights(["change_document", "change_own_document"])( - views.DocumentSelectView.as_view() - ), + check_permissions( + ["ishtar_common.change_document", "ishtar_common.change_own_document"] + )(views.DocumentSelectView.as_view()), name="edit-document", ), url( r"document/edit/(?P<pk>.+)/$", - check_rights(["change_document", "change_own_document"])( - views.DocumentEditView.as_view() - ), + check_permissions( + ["ishtar_common.change_document", "ishtar_common.change_own_document"] + )(views.DocumentEditView.as_view()), name="edit-document", ), url( r"document/delete/(?P<step>.+)?$", - check_rights(["change_document", "change_own_document"])( - views.document_deletion_wizard - ), + check_permissions( + ["ishtar_common.change_document", "ishtar_common.change_own_document"] + )(views.document_deletion_wizard), name="document_deletion", ), url( @@ -603,31 +649,31 @@ urlpatterns += [ ), url( r"^document-qa-bulk-update/(?P<pks>[0-9-]+)?/$", - check_rights(["change_document", "change_own_document"])( - views.QADocumentForm.as_view() - ), + check_permissions( + ["ishtar_common.change_document", "ishtar_common.change_own_document"] + )(views.QADocumentForm.as_view()), name="document-qa-bulk-update", ), url( r"^document-qa-bulk-update/(?P<pks>[0-9-]+)?/confirm/$", - check_rights(["change_document", "change_own_document"])( - views.QADocumentForm.as_view() - ), + check_permissions( + ["ishtar_common.change_document", "ishtar_common.change_own_document"] + )(views.QADocumentForm.as_view()), name="document-qa-bulk-update-confirm", kwargs={"confirm": True}, ), url( r"^document-qa-duplicate/(?P<pks>[0-9-]+)?/$", - check_rights(["change_document", "change_own_document"])( - views.QADocumentDuplicateFormView.as_view() - ), + check_permissions( + ["ishtar_common.change_document", "ishtar_common.change_own_document"] + )(views.QADocumentDuplicateFormView.as_view()), name="document-qa-duplicate", ), url( r"^document-qa-packaging/(?P<pks>[0-9-]+)?/$", - check_rights(["change_document", "change_own_document"])( - views.QADocumentPackagingFormView.as_view() - ), + check_permissions( + ["ishtar_common.change_document", "ishtar_common.change_own_document"] + )(views.QADocumentPackagingFormView.as_view()), name="document-qa-packaging", ), url( @@ -642,30 +688,32 @@ urlpatterns += [ ), url( r"geo/create/(?P<app_source>[-\w]+)/(?P<model_source>[-\w]+)/(?P<source_pk>\d+)/$", - check_rights(["add_geovectordata", "add_own_geovectordata"])( - views.GeoPreCreateView.as_view() - ), + check_permissions( + ["ishtar_common.add_geovectordata", "ishtar_common.add_own_geovectordata"] + )(views.GeoPreCreateView.as_view()), name="create-pre-geo", ), url( r"geo/create/(?P<app_source>[-\w]+)/(?P<model_source>[-\w]+)/(?P<source_pk>\d+)/(?P<geom_type>[-\w]+)/$", - check_rights(["add_geovectordata", "add_own_geovectordata"])( - views.GeoCreateView.as_view() - ), + check_permissions( + ["ishtar_common.add_geovectordata", "ishtar_common.add_own_geovectordata"] + )(views.GeoCreateView.as_view()), name="create-geo", ), url( r"geo/edit/(?P<pk>\d+)/$", - check_rights(["change_geovectordata", "change_own_geovectordata"])( - views.GeoEditView.as_view() - ), + check_permissions( + ["ishtar_common.change_geovectordata", + "ishtar_common.change_own_geovectordata"] + )(views.GeoEditView.as_view()), name="edit-geo", ), url( r"geo/delete/(?P<pk>\d+)/$", - check_rights(["change_geovectordata", "change_own_geovectordata"])( - views.GeoDeleteView.as_view() - ), + check_permissions( + ["ishtar_common.change_geovectordata", + "ishtar_common.change_own_geovectordata"] + )(views.GeoDeleteView.as_view()), name="delete-geo", ), url( diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 09e83714b..8de745874 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -21,8 +21,9 @@ from csv import QUOTE_ALL import datetime import feedparser from functools import wraps +from guardian.exceptions import WrongAppError from itertools import chain -from inspect import currentframe, getframeinfo +from inspect import currentframe import json import logging import hashlib @@ -225,24 +226,25 @@ def import_class(full_path_classname): return model -def check_rights(rights=None, redirect_url="/"): +def check_permissions(permissions=None, redirect_url="/"): """ Decorator that checks the rights to access the view. """ def decorator(view_func): def _wrapped_view(request, *args, **kwargs): - if not rights: + if not permissions: return view_func(request, *args, **kwargs) if hasattr(request.user, "ishtaruser"): - if request.user.ishtaruser.has_right("administrator", request.session): + ishtaruser = request.user.ishtaruser + if ishtaruser.has_permission("ishtaradmin"): kwargs["current_right"] = "administrator" return view_func(request, *args, **kwargs) - for right in rights: + for permission in permissions: # be careful to put the more permissive rights first # if granted it can allow more - if request.user.ishtaruser.has_right(right, request.session): - kwargs["current_right"] = right + if ishtaruser.has_permission(permission): + kwargs["current_right"] = permission return view_func(request, *args, **kwargs) put_session_message( request.session.session_key, @@ -256,17 +258,18 @@ def check_rights(rights=None, redirect_url="/"): return decorator -def check_rights_condition(rights): +def check_permissions_condition(permissions): """ To be used to check in wizard condition_dict """ def func(self): request = self.request - if request.user.ishtaruser.has_right("administrator", request.session): + ishtaruser = request.user.ishtaruser + if ishtaruser.has_permission("ishtaradmin"): return True - for right in rights: - if request.user.ishtaruser.has_right(right, request.session): + for permission in permissions: + if ishtaruser.has_permission(permission): return True return False @@ -297,7 +300,7 @@ def check_model_access_control(request, model, available_perms=None): ishtaruser = request.user.ishtaruser except request.user._meta.model.ishtaruser.RelatedObjectDoesNotExist: return False, True - if ishtaruser.has_right("administrator", session=request.session): + if ishtaruser.has_permission("ishtaradmin"): allowed = True own = False return allowed, own @@ -305,10 +308,10 @@ def check_model_access_control(request, model, available_perms=None): content_type__app_label=model._meta.app_label, content_type__model=model._meta.model_name ) - for perm in q.values_list("codename", flat=True): + for app_name, perm in q.values_list("content_type__app_label", "codename"): if perm not in available_perms: continue - if ishtaruser.person.has_right(perm, session=request.session): + if ishtaruser.has_permission(f"{app_name}.{perm}"): allowed = True if "_own_" not in perm: own = False @@ -343,48 +346,56 @@ class OwnPerms: return None # implement for each object def can_view(self, request): - if hasattr(self, "LONG_SLUG"): - perm = "view_" + self.LONG_SLUG - else: - perm = "view_" + self.SLUG + meta = self.__class__._meta + perm = f"{meta.app_label}.view_{meta.model_name}" return self.can_do(request, perm) def can_edit(self, request): if not getattr(request.user, "ishtaruser", None): return False ishtaruser = request.user.ishtaruser - slug = self.LONG_SLUG if hasattr(self, "LONG_SLUG") else self.SLUG - if ishtaruser.has_perm("change_" + slug, session=request.session): + meta = self.__class__._meta + perm = f"{meta.app_label}.change_{meta.model_name}" + if ishtaruser.has_permission(perm): return True - if not ishtaruser.has_perm("change_own_" + slug, session=request.session): + own_perm = f"{meta.app_label}.change_own_{meta.model_name}" + if not ishtaruser.has_permission(own_perm): return False return self.is_own(ishtaruser) - def can_do(self, request, action_name): + def can_do(self, request, permission): """ Check permission availability for the current object. :param request: request object - :param action_name: action name eg: "change_find" - "own" variation is - checked + :param permission: action name eg: "archaelogical_finds.change_find" - "own" + variation is checked :return: boolean """ if not getattr(request.user, "ishtaruser", None): return False - splited = action_name.split("_") - action_own_name = splited[0] + "_own_" + "_".join(splited[1:]) - user = request.user - if action_name == "view_findbasket": - action_own_name = "view_own_find" - action_name = "view_find" - return user.ishtaruser.has_right(action_name, request.session) or ( - user.ishtaruser.has_right(action_own_name, request.session) - and self.is_own(user.ishtaruser) - ) + + if "_findbasket" in permission: + permission = permission.replace("basket", "") + ishtaruser = request.user.ishtaruser + + if ishtaruser.has_permission(permission): + return True + app, perm = permission.split(".") + p = perm.split("_") + own = f"{app}.{p[0]}_own_{('_').join(p[1:])}" + try: + return ishtaruser.has_permission(own, self) + except WrongAppError: + # normaly occurs when, for instance, add doc permission is required + # for an item with document attached but the item is not a document. + # own permission is irrelevant: return False + return False def is_own(self, user, alt_query_own=None): """ Check if the current object is owned by the user """ + print("ishtar_common/utils.py - 370 - DELETE") IshtarUser = apps.get_model("ishtar_common", "IshtarUser") if isinstance(user, IshtarUser): ishtaruser = user @@ -406,6 +417,7 @@ class OwnPerms: """ Check if the user own some items """ + print("ishtar_common/utils.py - 392 - DELETE") IshtarUser = apps.get_model("ishtar_common", "IshtarUser") if isinstance(user, IshtarUser): ishtaruser = user @@ -1139,9 +1151,7 @@ def get_random_item_image_link(request): return "" ishtar_user = request.user.ishtaruser - if not ishtar_user.has_right( - "ishtar_common.view_document", session=request.session - ): + if not ishtar_user.has_permission("ishtar_common.view_document"): return "" q = ( @@ -1945,17 +1955,23 @@ def get_urls_for_model( """ Generate get and show url for a model """ + app_label = model._meta.app_label + model_name = model._meta.model_name urls = [ url( r"show-{}(?:/(?P<pk>.+))?/(?P<type>.+)?$".format(model.SLUG), - check_rights(["view_" + model.SLUG, "view_own_" + model.SLUG])( + check_permissions( + [f"{app_label}.view_{model_name}", + f"{app_label}.view_own_{model_name}"])( getattr(views, "show_" + model.SLUG) ), name="show-" + model.SLUG, ), url( r"^display-{}/(?P<pk>.+)/$".format(model.SLUG), - check_rights(["view_" + model.SLUG, "view_own_" + model.SLUG])( + check_permissions( + [f"{app_label}.view_{model_name}", + f"{app_label}.view_own_{model_name}"])( getattr(views, "display_" + model.SLUG) ), name="display-" + model.SLUG, @@ -1965,7 +1981,9 @@ def get_urls_for_model( urls += [ url( r"get-{}/own/(?P<type>.+)?$".format(model.SLUG), - check_rights(["view_" + model.SLUG, "view_own_" + model.SLUG])( + check_permissions( + [f"{app_label}.view_{model_name}", + f"{app_label}.view_own_{model_name}"])( getattr(views, "get_" + model.SLUG) ), name="get-own-" + model.SLUG, @@ -1976,7 +1994,9 @@ def get_urls_for_model( urls += [ url( r"get-{}/(?P<type>.+)?$".format(model.SLUG), - check_rights(["view_" + model.SLUG, "view_own_" + model.SLUG])( + check_permissions( + [f"{app_label}.view_{model_name}", + f"{app_label}.view_own_{model_name}"])( getattr(views, "get_" + model.SLUG) ), name="get-" + model.SLUG, @@ -1987,7 +2007,9 @@ def get_urls_for_model( urls += [ url( r"autocomplete-{}/$".format(model.SLUG), - check_rights(["view_" + model.SLUG, "view_own_" + model.SLUG])( + check_permissions( + [f"{app_label}.view_{model_name}", + f"{app_label}.view_own_{model_name}"])( getattr(views, "autocomplete_" + model.SLUG) ), name="autocomplete-" + model.SLUG, diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 780a2253b..6c209a848 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -863,7 +863,10 @@ def autocomplete_person_permissive( def autocomplete_user(request): - if not request.user.has_perm("ishtar_common.view_person", models.Person): + ishtaruser = getattr(request.user, "ishtaruser", None) + if not ishtaruser: + return HttpResponse("[]", content_type="text/plain") + if not ishtaruser.has_permission("ishtar_common.view_person"): return HttpResponse("[]", content_type="text/plain") q = request.GET.get("term") limit = request.GET.get("limit", 20) @@ -893,7 +896,10 @@ def autocomplete_user(request): def autocomplete_ishtaruser(request): - if not request.user.has_perm("ishtar_common.view_person", models.Person): + ishtaruser = getattr(request.user, "ishtaruser", None) + if not ishtaruser: + return HttpResponse("[]", content_type="text/plain") + if not ishtaruser.has_permission("ishtar_common.view_person"): return HttpResponse("[]", content_type="text/plain") q = request.GET.get("term", "") limit = request.GET.get("limit", 20) @@ -917,12 +923,13 @@ def autocomplete_ishtaruser(request): def autocomplete_person( request, person_types=None, attached_to=None, is_ishtar_user=None, permissive=False ): - all_items = request.user.has_perm("ishtar_common.view_person", models.Person) + 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 = request.user.has_perm( - "ishtar_common.view_own_person", models.Person - ) + own_items = ishtaruser.has_permission("ishtar_common.view_own_person") if not all_items and not own_items or not request.GET.get("term"): return HttpResponse("[]", content_type="text/plain") q = request.GET.get("term") @@ -966,12 +973,13 @@ def autocomplete_person( def autocomplete_import(request): - all_items = request.user.has_perm("ishtar_common.view_import", models.Import) + 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 = request.user.has_perm( - "ishtar_common.view_own_import", models.Import - ) + own_items = ishtaruser.has_permission("ishtar_common.view_own_import") if not all_items and not own_items or not request.GET.get("term"): return HttpResponse("[]", content_type="text/plain") q = request.GET.get("term") @@ -982,7 +990,8 @@ def autocomplete_import(request): return HttpResponseBadRequest() query = Q() for q in q.split(" "): - query = query & (Q(name__unaccent__icontains=q) | Q(group__name__unaccent__icontains=q)) + 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") @@ -1116,16 +1125,12 @@ 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 request.user.has_perm( - "ishtar_common.view_organization", models.Organization - ) - and not request.user.has_perm( - "ishtar_common.view_own_organization", models.Organization - ) - and not request.user.ishtaruser.has_right( - "person_search", session=request.session - ) + 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"): @@ -1149,9 +1154,13 @@ def autocomplete_organization(request, orga_type=None): def autocomplete_author(request): - if not request.user.has_perm( - "ishtar_common.view_author", models.Author - ) and not request.user.has_perm("ishtar_common.view_own_author", models.Author): + 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"): return HttpResponse("[]", content_type="text/plain") @@ -1172,7 +1181,10 @@ def autocomplete_author(request): def autocomplete_biographical_note(request): - if not request.user.has_perm("ishtar_common.view_person", models.Person): + ishtaruser = getattr(request.user, "ishtaruser", None) + if not ishtaruser: + return HttpResponse("[]", content_type="text/plain") + if not ishtaruser.has_permission("ishtar_common.view_person"): return HttpResponse("[]", content_type="text/plain") q = request.GET.get("term", "") limit = request.GET.get("limit", 20) @@ -1637,18 +1649,20 @@ class NewImportView(BaseImportView, CreateView): class ImportPermissionMixin: - permission_full = "change_import" - permission_own = "change_own_import" + permission_full = "ishtar_common.change_import" + permission_own = "ishtar_common.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("/") + ishtaruser = user.ishtaruser 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): + if not ishtaruser.has_permission("ishtaradmin") and \ + not ishtaruser.has_permission(self.permission_full): + if not ishtaruser.has_permission(self.permission_own): return redirect("/") q = q.filter(Q(importer_type__users__pk=user.ishtaruser.pk)) if not q.count(): @@ -1711,7 +1725,8 @@ 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): +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 @@ -1741,21 +1756,38 @@ class ImportListView(IshtarMixin, LoginRequiredMixin, ListView): user = self.request.user if not user.pk or not user.ishtaruser: raise Http404() - q1 = self._queryset_filter(self.model.query_can_access(user, ["view_import", "change_import"])) + q1 = self._queryset_filter( + self.model.query_can_access( + user, + ["ishtar_common.view_import", "ishtar_common.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, ["view_import", "change_import"])) - q2 = q2.order_by("-end_date", "-creation_date", "-pk") - 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 + q2 = self._queryset_filter( + models.ImportGroup.query_can_access( + user, + ["ishtar_common.view_import", "ishtar_common.change_import"] + ) ) + q2 = q2.order_by("-end_date", "-creation_date", "-pk") + 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) 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 + 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 ) - imprt.action_list = imprt.get_actions(can_edit=can_edit, can_delete=can_delete) imports.append(imprt) self.imports_len = len(imports) self.current_page = 0 @@ -1768,9 +1800,8 @@ class ImportListView(IshtarMixin, LoginRequiredMixin, ListView): 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 - ) + can_edit_all, can_delete_all, can_edit_own, can_delete_own = \ + models.Import.get_permissions_for_actions(request.user) owns = {} for field in request.POST: if not field.startswith("import-action-") or not request.POST[field]: @@ -1785,7 +1816,8 @@ class ImportListView(IshtarMixin, LoginRequiredMixin, ListView): except (models.Import.DoesNotExist, ValueError): 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 + request.user, imprt, owns, can_edit_all, + can_delete_all, can_edit_own, can_delete_own ) action = request.POST[field] if can_delete and action == "D": @@ -1843,15 +1875,28 @@ class ImportListView(IshtarMixin, LoginRequiredMixin, ListView): if self.imports_len > self.page_step and self.pagination: dct["current_page"] = self.current_page dct["page_range"] = (n + 1 for n in range(self.page_number)) - 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') + add_import_perm = self.request.user.ishtaruser.has_permission( + "ishtar_common.add_import" + ) + 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) + ishtaruser = self.request.user.ishtaruser + if not add_import_perm and ishtaruser.has_permission( + "ishtar_common.add_own_import"): + 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: @@ -2313,11 +2358,11 @@ def import_get_status(request, current_right=None): "number_of_line": item.number_of_line, "progress_percent": item.progress_percent, }) - can_edit_all, can_delete_all, can_edit_own, can_delete_own = models.Import.get_permissions_for_actions( - request.user, request.session - ) + 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 + request.user, item, {}, can_edit_all, + can_delete_all, can_edit_own, can_delete_own ) item_dct["actions"] = [ (key, str(lbl)) @@ -2404,11 +2449,11 @@ class ImportCSVView(ImportPermissionMixin, IshtarMixin, LoginRequiredMixin, Temp TITLES = { "source": ("fa fa-file-text-o", _("Source")), "error": ("text-danger fa fa-exclamation-triangle", _("Error")), - "result": ("fa fa-th", _("Result")) , + "result": ("fa fa-th", _("Result")), "match": ("fa fa-arrows-h", _("Match")), } - permission_full = "view_import" - permission_own = "view_own_import" + permission_full = "ishtar_common.view_import" + permission_own = "ishtar_common.view_own_import" def get(self, request, *args, **kwargs): user = self.request.user @@ -2416,7 +2461,9 @@ class ImportCSVView(ImportPermissionMixin, IshtarMixin, LoginRequiredMixin, Temp raise Http404() self.is_group = kwargs.get("group", None) model = models.ImportGroup if self.is_group else models.Import - q = model.query_can_access(self.request.user, perm=self.permission_full).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] @@ -2491,7 +2538,9 @@ def line_error(request, line_id, current_right=None): if not q.count(): return line = q.all()[0] - q = models.Import.query_can_access(request.user, perm="change_import").filter(pk=line.import_item_id) + q = models.Import.query_can_access( + request.user, perm="ishtar_common.change_import" + ).filter(pk=line.import_item_id) if not q.count(): raise Http404() line.ignored = not line.ignored @@ -2853,7 +2902,12 @@ def get_bookmark(request, pk): def gen_generate_doc(model): def func(request, pk, template_pk=None): - if not request.user.has_perm("view_" + model.SLUG, model): + ishtaruser = getattr(request.user, "ishtaruser", None) + if not ishtaruser: + return HttpResponse(content_type="text/plain") + meta = model._meta + perm = f"{meta.app_label}.view_{meta.model_name}" + if not ishtaruser.has_permission(perm): return HttpResponse(content_type="text/plain") try: item = model.objects.get(pk=pk) @@ -3075,10 +3129,10 @@ class QAItemForm(IshtarMixin, LoginRequiredMixin, FormView): quick_action = self.get_quick_action() if not quick_action: raise Http404() - if not quick_action.is_available(user=request.user, session=request.session): + if not quick_action.is_available(user=request.user): for item in self.items: if not quick_action.is_available( - user=request.user, session=request.session, obj=item + user=request.user, obj=item ): raise Http404() @@ -3431,13 +3485,15 @@ class GeoCreateView(GeoFormMixin, CreateView): obj = model.objects.get(pk=self.kwargs.get("source_pk")) except model.DoesNotExist: raise Http404() - if not ishtaruser.has_perm("add_geovectordata"): # -> add_own_geovectordata + if not ishtaruser.has_permission( + "ishtar_common.add_geovectordata"): + # -> add_own_geovectordata # check permission to view attached item - if not getattr(model, "SLUG", None): - raise Http404() - if not ishtaruser.has_right(f"view_{model.SLUG}") \ - or not ishtaruser.has_right(f"view_own_{model.SLUG}") \ - or not obj.is_own(ishtaruser): + meta = model._meta + perm = f"{meta.app_label}.view_{meta.model_name}" + perm_own = f"{meta.app_label}.view_own_{meta.model_name}" + if not ishtaruser.has_permission(perm) \ + and not ishtaruser.has_permission(perm_own, obj=obj): # check permission to view own attached item raise Http404() kwargs["main_items_fields"] = {} diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 48d8e229b..a88cb48b3 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -222,11 +222,9 @@ def check_permission(request, action_slug, obj_id=None): return True if obj_id: return main_menu.items[action_slug].is_available( - request.user, obj_id, session=request.session + request.user, obj_id ) - return main_menu.items[action_slug].can_be_available( - request.user, session=request.session - ) + return main_menu.items[action_slug].can_be_available(request.user) def new_qa_item( diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 43e84fbcb..e41c4c811 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -55,25 +55,6 @@ from ishtar_common.utils import get_all_field_names, get_person_gdpr_log, MultiV logger = logging.getLogger(__name__) -# buggy and unecessary at least for the moment... -""" -def _check_right(step, condition=True): - '''Return a method to check the right for a specific step''' - def check_right(self): - cond = condition - if callable(condition): - cond = condition(self) - if not cond: - return False - return True - # TODO: to be check - if not hasattr(self.request.user, 'ishtaruser'): - return False - return self.request.user.ishtaruser.has_right( - ('administrator', step), session=self.request.session) - return check_right -""" - def filter_no_fields_form(form, other_check=None): def func(self): |