def _filter_children(parent_path, **kwargs): parent_node = get_node(parent_path) content_type = kwargs.has_key('content_type') and kwargs.pop('content_type') if content_type: return _filter_children_by_content_type(parent_node, content_type, **kwargs) content_types_exclude = kwargs['content_types_exclude'] if not kwargs['content_filter_kwargs']: # not searching by content type and content filter not set # return all children children_nodes_qs = get_children(parent_node=parent_node) if kwargs['offline_filter']: # filter out offline recs children_nodes_qs = children_nodes_qs.filter(offline=False) if kwargs.has_key('active'): children_nodes_qs = children_nodes_qs.filter(active=kwargs['active']) return children_nodes_qs.exclude(content_type__in=content_types_exclude).order_by('content_type', 'seq_num') logger.warning('expensive filter across multiple content types ("ct" not specified), content filter: %s' % kwargs['content_filter_kwargs']) # limit search to possible children content types only # by inspecting children constraints children_nodes = [] CHILDREN_CONSTRAINT = [] if parent_node: parent_content_type = parent_node.content_type parent_model_class = parent_content_type.model_class() if hasattr(parent_model_class, 'CHILDREN_CONSTRAINT'): CHILDREN_CONSTRAINT = parent_model_class.CHILDREN_CONSTRAINT else: # searching children at site root CHILDREN_CONSTRAINT = settings.SITEROOT_CHILDREN_CONSTRAINT for cc in CHILDREN_CONSTRAINT: #XXX TEST THIS constraint_content_types = [] model_cls = get_model(*cc['content_type_name'].split('.')) if issubclass(model_cls, TreeContent): constraint_content_types.append(get_content_type(*cc['content_type_name'].split('.'))) else: # could be a generic parent class with concrete TreeContent subclasses for sc in model_cls.__subclasses__(): if issubclass(sc, TreeContent): sc_ct = get_content_type(sc._meta.app_label, sc._meta.object_name.lower()) constraint_content_types.append(sc_ct) for ct in constraint_content_types: if ct in content_types_exclude: # auth filter - exclude from results continue for n in _filter_children_by_content_type(parent_node, ct, **kwargs): logger.debug("found node - %s" % n.absolute_path) children_nodes.append(n) return children_nodes
def is_authorization_required(action, content_type_name='', content_type=None): """Is authorization required to perform `action` on objects of the content type. Valid action arg values: 'add', 'change', 'delete', 'read' """ if not action in ['add','change','delete','read']: logger.error('invalid action: "%s"' % action) return True if not content_type: if content_type_name: content_type = get_content_type(*content_type_name.split('.')) if not content_type: logger.error('invalid content type name: "%s"' % content_type_name) return True perm_codename = action + '_' + content_type.model try: perm = Permission.objects.get(content_type=content_type, codename=perm_codename) # yes, need to authorize to perform `action` logger.debug('Permissions "%s" for ct "%s" found. Action auth is required.' % (perm_codename, content_type)) return True except Permission.DoesNotExist: # no permission for the content type return False
def create(request, tree_context_path, *args, **kwargs): content_type_name = request.GET.get('ct') or request.POST.get('ct') if not content_type_name: #XXX invalid request?? logger.error('ct not set') raise Http404 content_type = get_content_type(*content_type_name.split('.')) if not content_type: logger.error('invalid ct: "%s"' % content_type_name) raise Http404 # when creating/adding new content, context is parent of object being added if request.tree_context.path == '/': parent_object = None else: parent_object = request.tree_context.node.content_object create_view_cls = query_component('CreateView', (parent_object, content_type), name=content_type_name) if not create_view_cls: # generic view create_view_cls = GenericCreateView logger.debug("Create View class: %s" % create_view_cls) #hacky, needed for portlets (portlet context_processors.py) request.view_component = create_view_cls view_func = create_view_cls.as_view(parent_object=parent_object, content_type=content_type, content_type_name=content_type_name, **kwargs) return view_func(request)
def is_authorization_required(action, content_type_name='', content_type=None): """Is authorization required to perform `action` on objects of the content type. Valid action arg values: 'add', 'change', 'delete', 'read' """ if not action in ['add', 'change', 'delete', 'read']: logger.error('invalid action: "%s"' % action) return True if not content_type: if content_type_name: content_type = get_content_type(*content_type_name.split('.')) if not content_type: logger.error('invalid content type name: "%s"' % content_type_name) return True perm_codename = action + '_' + content_type.model try: perm = Permission.objects.get(content_type=content_type, codename=perm_codename) # yes, need to authorize to perform `action` logger.debug( 'Permissions "%s" for ct "%s" found. Action auth is required.' % (perm_codename, content_type)) return True except Permission.DoesNotExist: # no permission for the content type return False
def _preprocess_kwargs(kwargs): content_type = None if kwargs.has_key('ct'): content_type_name = kwargs.pop('ct') content_type = get_content_type(*content_type_name.split('.')) if not content_type: raise TreeSearchError('invalid content type: "%s"' % content_type_name) tree_context = kwargs.has_key('tree_context') and kwargs.pop('tree_context') if tree_context: # search within tree context checking authenticated/anonymous user # and user permissions # default - anonymous user cannot read content requiring read permission # nor offline content content_types_exclude = settings.READ_PERMISSION_CONTENT_TYPES offline_filter = True if tree_context.authenticated_user: # we have authenticated user if tree_context.authenticated_user.is_superuser: # can read everything content_types_exclude = [] # can see offline content offline_filter = False else: if tree_context.user_permissions: # user has perms at node, so not outside their branch # auth user can see offline content inside their branch offline_filter = False # get user's read permissions read_content_types = [] for p in tree_context.user_permissions: if 'read_' in p.codename: read_content_types.append(p.content_type) # allow user to read content which she has read permissions for content_types_exclude = list(set(settings.READ_PERMISSION_CONTENT_TYPES) - set(read_content_types)) else: # search - no auth content_types_exclude = [] offline_filter = False # clean content filter kwargs content_filter_kwargs = kwargs.copy() if content_filter_kwargs.has_key('include_self'): # lookup search specific param - remove from content filter del(content_filter_kwargs['include_self']) if content_filter_kwargs.has_key('active'): # searching only 'active' nodes - remove from content filter del(content_filter_kwargs['active']) kwargs['content_filter_kwargs'] = content_filter_kwargs kwargs['content_type'] = content_type kwargs['content_types_exclude'] = content_types_exclude kwargs['offline_filter'] = offline_filter
def authorize_wrapper(request, tree_context_path='/'): logger.debug('request path ' + request.path) if hasattr(settings, 'TREE_AUTH_OFF') and settings.TREE_AUTH_OFF: logger.warning( 'TREE_AUTH_OFF set, not performing request auth') return func(request, tree_context_path) if hasattr(request, 'user'): # have user object - front end with django auth enabled if request.user.is_authenticated( ) and request.user.is_active and request.user.is_superuser: logger.debug("authorized superuser - running %s" % str(func)) return func(request, tree_context_path) if not self.action: if request.path.endswith('create'): self.action = 'create' elif request.path.endswith('update'): self.action = 'update' elif request.path.endswith('delete'): self.action = 'delete' if self.action == 'create': create_content_type_name = request.GET.get( 'ct') or request.POST.get('ct') create_content_type = get_content_type( *create_content_type_name.split('.')) if not create_content_type: logger.error('could not set content type') raise Http400 #XXX test if is_authorized('add', request.tree_context, content_type=create_content_type): return func(request, tree_context_path) elif self.action == 'update': if is_authorized('change', request.tree_context): return func(request, tree_context_path) elif self.action == 'delete': if is_authorized('delete', request.tree_context): return func(request, tree_context_path) else: if is_authorized('read', request.tree_context): return func(request, tree_context_path) # Unauthorized raise Http401 #XXX test this
def authorize_wrapper(request, tree_context_path='/'): logger.debug('request path ' + request.path) if hasattr(settings, 'TREE_AUTH_OFF') and settings.TREE_AUTH_OFF: logger.warning('TREE_AUTH_OFF set, not performing request auth') return func(request, tree_context_path) if hasattr(request, 'user'): # have user object - front end with django auth enabled if request.user.is_authenticated() and request.user.is_active and request.user.is_superuser: logger.debug("authorized superuser - running %s" % str(func)) return func(request, tree_context_path) if not self.action: if request.path.endswith('create'): self.action = 'create' elif request.path.endswith('update'): self.action = 'update' elif request.path.endswith('delete'): self.action = 'delete' if self.action == 'create': create_content_type_name = request.GET.get('ct') or request.POST.get('ct') create_content_type = get_content_type(*create_content_type_name.split('.')) if not create_content_type: logger.error('could not set content type') raise Http400 #XXX test if is_authorized('add', request.tree_context, content_type=create_content_type): return func(request, tree_context_path) elif self.action == 'update': if is_authorized('change', request.tree_context): return func(request, tree_context_path) elif self.action == 'delete': if is_authorized('delete', request.tree_context): return func(request, tree_context_path) else: if is_authorized('read', request.tree_context): return func(request, tree_context_path) # Unauthorized raise Http401 #XXX test this
def _preprocess_kwargs(kwargs): content_type = None if kwargs.has_key('ct'): content_type_name = kwargs.pop('ct') content_type = get_content_type(*content_type_name.split('.')) if not content_type: raise TreeSearchError('invalid content type: "%s"' % content_type_name) tree_context = kwargs.has_key('tree_context') and kwargs.pop( 'tree_context') if tree_context: # search within tree context checking authenticated/anonymous user # and user permissions # default - anonymous user cannot read content requiring read permission # nor offline content content_types_exclude = settings.READ_PERMISSION_CONTENT_TYPES offline_filter = True if tree_context.authenticated_user: # we have authenticated user if tree_context.authenticated_user.is_superuser: # can read everything content_types_exclude = [] # can see offline content offline_filter = False else: if tree_context.user_permissions: # user has perms at node, so not outside their branch # auth user can see offline content inside their branch offline_filter = False # get user's read permissions read_content_types = [] for p in tree_context.user_permissions: if 'read_' in p.codename: read_content_types.append(p.content_type) # allow user to read content which she has read permissions for content_types_exclude = list( set(settings.READ_PERMISSION_CONTENT_TYPES) - set(read_content_types)) else: # search - no auth content_types_exclude = [] offline_filter = False # clean content filter kwargs content_filter_kwargs = kwargs.copy() if content_filter_kwargs.has_key('include_self'): # lookup search specific param - remove from content filter del (content_filter_kwargs['include_self']) if content_filter_kwargs.has_key('active'): # searching only 'active' nodes - remove from content filter del (content_filter_kwargs['active']) kwargs['content_filter_kwargs'] = content_filter_kwargs kwargs['content_type'] = content_type kwargs['content_types_exclude'] = content_types_exclude kwargs['offline_filter'] = offline_filter
def _filter_children(parent_path, **kwargs): parent_node = get_node(parent_path) content_type = kwargs.has_key('content_type') and kwargs.pop( 'content_type') if content_type: return _filter_children_by_content_type(parent_node, content_type, **kwargs) content_types_exclude = kwargs['content_types_exclude'] if not kwargs['content_filter_kwargs']: # not searching by content type and content filter not set # return all children children_nodes_qs = get_children(parent_node=parent_node) if kwargs['offline_filter']: # filter out offline recs children_nodes_qs = children_nodes_qs.filter(offline=False) if kwargs.has_key('active'): children_nodes_qs = children_nodes_qs.filter( active=kwargs['active']) return children_nodes_qs.exclude( content_type__in=content_types_exclude).order_by( 'content_type', 'seq_num') logger.warning( 'expensive filter across multiple content types ("ct" not specified), content filter: %s' % kwargs['content_filter_kwargs']) # limit search to possible children content types only # by inspecting children constraints children_nodes = [] CHILDREN_CONSTRAINT = [] if parent_node: parent_content_type = parent_node.content_type parent_model_class = parent_content_type.model_class() if hasattr(parent_model_class, 'CHILDREN_CONSTRAINT'): CHILDREN_CONSTRAINT = parent_model_class.CHILDREN_CONSTRAINT else: # searching children at site root CHILDREN_CONSTRAINT = settings.SITEROOT_CHILDREN_CONSTRAINT for cc in CHILDREN_CONSTRAINT: #XXX TEST THIS constraint_content_types = [] model_cls = get_model(*cc['content_type_name'].split('.')) if issubclass(model_cls, TreeContent): constraint_content_types.append( get_content_type(*cc['content_type_name'].split('.'))) else: # could be a generic parent class with concrete TreeContent subclasses for sc in model_cls.__subclasses__(): if issubclass(sc, TreeContent): sc_ct = get_content_type(sc._meta.app_label, sc._meta.object_name.lower()) constraint_content_types.append(sc_ct) for ct in constraint_content_types: if ct in content_types_exclude: # auth filter - exclude from results continue for n in _filter_children_by_content_type(parent_node, ct, **kwargs): logger.debug("found node - %s" % n.absolute_path) children_nodes.append(n) return children_nodes