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): | 
