diff options
Diffstat (limited to 'ishtar_common')
-rw-r--r-- | ishtar_common/backend.py | 18 | ||||
-rw-r--r-- | ishtar_common/context_processors.py | 3 | ||||
-rw-r--r-- | ishtar_common/menu_base.py | 34 | ||||
-rw-r--r-- | ishtar_common/menus.py | 17 | ||||
-rw-r--r-- | ishtar_common/models.py | 48 | ||||
-rw-r--r-- | ishtar_common/views.py | 30 | ||||
-rw-r--r-- | ishtar_common/wizards.py | 4 |
7 files changed, 99 insertions, 55 deletions
diff --git a/ishtar_common/backend.py b/ishtar_common/backend.py index 7ebdab221..0febd61b2 100644 --- a/ishtar_common/backend.py +++ b/ishtar_common/backend.py @@ -21,22 +21,18 @@ Permission backend to manage "own" objects """ -from django.conf import settings -from django.contrib.auth.models import User +from django.contrib.auth.backends import ModelBackend from django.core.exceptions import ObjectDoesNotExist from django.db.models.loading import cache import models -class ObjectPermBackend(object): + +class ObjectPermBackend(ModelBackend): supports_object_permissions = True supports_anonymous_user = True - def authenticate(self, username, password): - # managed by the default backend - return None - - def has_perm(self, user_obj, perm, model=None, obj=None): + def has_perm(self, user_obj, perm, model=None, obj=None, session=None): if not user_obj.is_authenticated(): return False if not model: @@ -50,10 +46,10 @@ class ObjectPermBackend(object): is_ownperm = perm.split('.')[-1].split('_')[1] == 'own' except IndexError: is_ownperm = False - if ishtar_user.has_right('administrator'): + if ishtar_user.has_right('administrator', session=session): return True - main_right = ishtar_user.person.has_right(perm) \ - or user_obj.has_perm(perm) + main_right = ishtar_user.person.has_right(perm, session=session) \ + or user_obj.has_perm(perm) if not main_right or not is_ownperm: return main_right if obj is None: diff --git a/ishtar_common/context_processors.py b/ishtar_common/context_processors.py index 20b7f119a..ce303c344 100644 --- a/ishtar_common/context_processors.py +++ b/ishtar_common/context_processors.py @@ -58,7 +58,8 @@ def get_base_context(request): if 'CURRENT_ACTION' in request.session: dct['CURRENT_ACTION'] = request.session['CURRENT_ACTION'] current_action = dct['CURRENT_ACTION'] - menu = Menu(request.user, current_action=current_action) + menu = Menu(request.user, current_action=current_action, + session=request.session) menu.init() if menu.selected_idx is not None: dct['current_theme'] = "theme-%d" % (menu.selected_idx + 1) diff --git a/ishtar_common/menu_base.py b/ishtar_common/menu_base.py index 2331ecbd7..ab0a43d41 100644 --- a/ishtar_common/menu_base.py +++ b/ishtar_common/menu_base.py @@ -17,6 +17,7 @@ # See the file COPYING for details. + class SectionItem: def __init__(self, idx, label, childs=[]): self.idx = idx @@ -25,27 +26,29 @@ class SectionItem: self.available = False self.items = {} - def can_be_available(self, user): + def can_be_available(self, user, session=None): for child in self.childs: - if child.can_be_available(user): + if child.can_be_available(user, session=session): return True return False - def is_available(self, user, obj=None): + def is_available(self, user, obj=None, session=None): for child in self.childs: - if child.is_available(user, obj): + if child.is_available(user, obj, session=session): return True return False - def set_items(self, user, items, current_action=None): + def set_items(self, user, items, current_action=None, session=None): selected = None if user: - self.available = self.can_be_available(user) + self.available = self.can_be_available(user, session=session) for child in self.childs: - selected = child.set_items(user, items, current_action) or selected + selected = child.set_items(user, items, current_action, + session=session) or selected items[child.idx] = child return selected + class MenuItem: def __init__(self, idx, label, model=None, access_controls=[]): self.idx = idx @@ -54,22 +57,24 @@ class MenuItem: self.access_controls = access_controls self.available = False - def can_be_available(self, user): + def can_be_available(self, user, session=None): if not self.access_controls: return True prefix = (self.model._meta.app_label + '.') if self.model else '' for access_control in self.access_controls: access_control = prefix + access_control - if user.has_perm(access_control, self.model) or \ + if hasattr(user, 'ishtaruser') and \ + user.ishtaruser.has_perm(access_control, self.model, + session=session) or \ access_control in user.get_group_permissions(): return True # manage by person type if hasattr(user, 'ishtaruser'): - if user.ishtaruser.has_right(self.idx): + if user.ishtaruser.has_right(self.idx, session=session): return True return False - def is_available(self, user, obj=None): + def is_available(self, user, obj=None, session=None): if not self.access_controls: return True prefix = (self.model._meta.app_label + '.') if self.model else '' @@ -79,13 +84,12 @@ class MenuItem: return True # manage by person type if hasattr(user, 'ishtaruser'): - if ishtar_user.has_right(self.idx): + if user.ishtaruser.has_right(self.idx, session=session): return True return False - def set_items(self, user, items, current_action=None): + def set_items(self, user, items, current_action=None, session=None): if user: - self.available = self.can_be_available(user) + self.available = self.can_be_available(user, session=session) if self.idx == current_action: return True - diff --git a/ishtar_common/menus.py b/ishtar_common/menus.py index 6333a4197..e55b288bf 100644 --- a/ishtar_common/menus.py +++ b/ishtar_common/menus.py @@ -22,10 +22,7 @@ Menus """ from django.conf import settings -from django.utils.translation import ugettext_lazy as _ -from menu_base import SectionItem, MenuItem -import models _extra_menus = [] # collect menu from INSTALLED_APPS @@ -36,8 +33,8 @@ for app in settings.INSTALLED_APPS: _extra_menus += menu.MENU_SECTIONS # sort -__section_items = [menu for order, menu in sorted(_extra_menus, - key=lambda x:x[0])] +__section_items = [mnu for order, mnu in sorted(_extra_menus, + key=lambda x:x[0])] # regroup menus _section_items, __keys = [], [] for section_item in __section_items: @@ -51,22 +48,26 @@ for section_item in __section_items: if child.idx not in childs_idx: section_childs.append(child) + class Menu: childs = _section_items - def __init__(self, user, current_action=None): + + def __init__(self, user, current_action=None, session=None): self.user = user self.initialized = False self.items = {} self.current_action = current_action self.selected_idx = None + self.session = session def init(self): if self.initialized: return self.items = {} for idx, main_menu in enumerate(self.childs): - selected = main_menu.set_items(self.user, self.items, - self.current_action) + selected = main_menu.set_items( + self.user, self.items, + self.current_action, session=self.session) if selected: self.selected_idx = idx self.initialized = True diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 72b41e0cf..b5e371b25 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -434,6 +434,18 @@ class GeneralType(models.Model): for item in cls.objects.all(): item.generate_key() + @classmethod + def get_cache(cls, slug): + cache_key, value = get_cache(cls, slug) + if value: + return value + try: + obj = cls.objects.get(txt_idx=slug) + cache.set(cache_key, obj, settings.CACHE_TIMEOUT) + return obj + except cls.DoesNotExist: + return None + class ItemKey(models.Model): key = models.CharField(_(u"Key"), max_length=100) @@ -1938,19 +1950,29 @@ class Person(Address, Merge, OwnPerms, ValueGetter): def is_natural(self): return not self.attached_to - def has_right(self, right_name): + def has_right(self, right_name, session=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 if type(right_name) in (list, tuple): - return bool(self.person_types.filter( + res = bool(self.person_types.filter( txt_idx__in=right_name).count()) or \ bool(self.person_types.filter( groups__permissions__codename__in=right_name).count()) # or self.person_types.filter(wizard__url_name__in=right_name).count()) - return bool(self.person_types.filter(txt_idx=right_name).count()) or \ - bool(self.person_types.filter( - groups__permissions__codename=right_name).count()) + else: + res = bool(self.person_types.filter(txt_idx=right_name).count()) or \ + bool(self.person_types.filter( + groups__permissions__codename=right_name).count()) # or self.person_types.filter(wizard__url_name=right_name).count()) + if session: + cache.set(cache_key, res, settings.CACHE_SMALLTIMEOUT) + return res def full_label(self): values = [] @@ -2010,12 +2032,24 @@ class IshtarUser(User): return IshtarUser.objects.create(user_ptr=user, username=default, person=person) - def has_right(self, right_name): - return self.person.has_right(right_name) + def has_right(self, right_name, session=None): + return self.person.has_right(right_name, session=session) def full_label(self): return self.person.full_label() + def has_perm(self, perm, model=None, session=None): + if not session: + return super(IshtarUser, self).has_perm(perm, model) + cache_key = 'usersession-{}-{}'.format(session.session_key, perm, + model or 'no') + res = cache.get(cache_key) + if res in (True, False): + return res + res = super(IshtarUser, self).has_perm(perm, model) + cache.set(cache_key, res, settings.CACHE_SMALLTIMEOUT) + return res + class AuthorType(GeneralType): class Meta: diff --git a/ishtar_common/views.py b/ishtar_common/views.py index ac29236ff..79e816bcb 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -167,21 +167,27 @@ def check_permission(request, action_slug, obj_id=None): # TODO return True if obj_id: - return menu.items[action_slug].is_available(request.user, obj_id) - return menu.items[action_slug].can_be_available(request.user) + return menu.items[action_slug].is_available(request.user, obj_id, + session=request.session) + return menu.items[action_slug].can_be_available(request.user, + session=request.session) -def autocomplete_person_permissive(request, person_types=None, attached_to=None, - is_ishtar_user=None): - return autocomplete_person(request, person_types=person_types, attached_to=attached_to, - is_ishtar_user=is_ishtar_user, permissive=True) +def autocomplete_person_permissive(request, person_types=None, + attached_to=None, is_ishtar_user=None): + return autocomplete_person( + request, person_types=person_types, attached_to=attached_to, + is_ishtar_user=is_ishtar_user, permissive=True) def autocomplete_person(request, person_types=None, attached_to=None, is_ishtar_user=None, permissive=False): - if not request.user.has_perm('ishtar_common.view_person', models.Person) and \ - not request.user.has_perm('ishtar_common.view_own_person', models.Person) \ - and not request.user.ishtaruser.has_right('person_search'): + if not request.user.has_perm('ishtar_common.view_person', + models.Person) and \ + not request.user.has_perm('ishtar_common.view_own_person', + models.Person) \ + and not request.user.ishtaruser.has_right('person_search', + session=request.session): return HttpResponse(mimetype='text/plain') if not request.GET.get('term'): return HttpResponse(mimetype='text/plain') @@ -325,7 +331,8 @@ def get_item(model, func_name, default_name, extra_request_keys=[], continue if request.user.has_perm(model._meta.app_label + '.' + perm) \ or (request.user.is_authenticated() - and request.user.ishtaruser.has_right(perm)): + and request.user.ishtaruser.has_right( + perm, session=request.session)): allowed = True if "_own_" not in perm: own = False @@ -760,7 +767,8 @@ def autocomplete_organization(request, orga_type=None): models.Organization) and not request.user.has_perm('ishtar_common.view_own_organization', models.Organization) - and not request.user.ishtaruser.has_right('person_search')): + and not request.user.ishtaruser.has_right( + 'person_search', session=request.session)): return HttpResponse(mimetype='text/plain') if not request.GET.get('term'): return HttpResponse(mimetype='text/plain') diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 8fe1b5da2..45b46eb63 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -74,8 +74,8 @@ class Wizard(NamedUrlWizardView): # TODO: to be check if not hasattr(self.request.user, 'ishtaruser'): return False - return self.request.user.ishtaruser.has_right(('administrator', - step)) + return self.request.user.ishtaruser.has_right( + ('administrator', step), session=self.request.session) return check_right def __init__(self, *args, **kwargs): |