Beispiel #1
0
    def queryset(self, request):
        """
        First semi-working draft of category-based permissions. It will allow permissions to be set per category
        effectively hiding the content the user has no permission to see/change.
        """
        q = super(NewmanModelAdmin, self).queryset(request)
        # user category filter
        qs = utils.user_category_filter(q, request.user)

        # if self.model is licensed filter queryset
        if License._meta.installed:
            exclude_pks = License.objects.unapplicable_for_model(self.model)
            qs_tmp = qs.exclude(pk__in=exclude_pks)
            utils.copy_queryset_flags(qs_tmp, qs)
            qs = qs_tmp

        if request.user.is_superuser:
            return qs
        view_perm = self.opts.app_label + '.' + 'view_' + self.model._meta.module_name.lower()
        change_perm = self.opts.app_label + '.' + 'change_' + self.model._meta.module_name.lower()
        perms = (view_perm, change_perm,)
#        return permission_filtered_model_qs(qs, request.user, perms)
        qs_tmp = permission_filtered_model_qs(qs, request.user, perms)
        utils.copy_queryset_flags(qs_tmp, qs)
        return qs_tmp
Beispiel #2
0
 def filter_func(self):
     qs = Category.objects.filter(pk__in=applicable_categories(self.user))
     lookup_var = self.get_lookup_kwarg()
     for cat in user_category_filter(qs, self.user):
         link = (cat, {lookup_var: cat.pk})
         self.links.append(link)
     return True
Beispiel #3
0
    def newman_index(self, request, extra_context=None):
        def translate_and_upper(text):
            return ugettext(text).upper()

        """
        Displays the main Newman index page, without installed apps.
        """
        data = {'sites': []}
        try:
            data['sites'] = get_user_config(request.user,
                                            newman_settings.CATEGORY_FILTER)
        except KeyError:
            data['sites'] = []

        publishable_lookup_fields = {
            'day': 'publish_from__day',
            'month': 'publish_from__month',
            'year': 'publish_from__year'
        }
        site_filter_form = SiteFilterForm(data=data, user=request.user)
        if site_filter_form.sites_count == 1:
            site_filter_form = None
        cts = []
        last_filters = {}
        for model, model_admin in self._registry.items():
            if has_model_list_permission(request.user,
                                         model) and model_admin.search_fields:
                ct = ContentType.objects.get_for_model(model)
                cts.append(ct)
                # Load saved filter configurations for changelists
                key = 'filter__%s__%s' % (ct.app_label, ct.model)
                last_filter = AdminSetting.objects.filter(var=key,
                                                          user=request.user)
                if last_filter:
                    last_filters[key] = '?%s' % json_decode(
                        last_filter[0].value)

        future_qs = Placement.objects.select_related().filter(
            publish_from__gt=datetime.datetime.now()).order_by(
                'publish_from', 'category__tree_path')
        future_qs_perm = permission_filtered_model_qs(future_qs, request.user)
        future_placements = user_category_filter(future_qs_perm, request.user)

        cts.sort(lambda a, b: cz_compare(translate_and_upper(a.name),
                                         translate_and_upper(b.name)))
        context = {
            'title': _('Site administration'),
            'site_filter_form': site_filter_form,
            'searchable_content_types': cts,
            'last_filters': last_filters,
            'future_placements': future_placements,
            'publishable_lookup_fields': publishable_lookup_fields,
            'show_calendar': has_model_list_permission(request.user,
                                                       Publishable),
        }
        context.update(extra_context or {})
        return render_to_response(
            'newman/newman-index.html',
            context,
            context_instance=template.RequestContext(request))
Beispiel #4
0
 def filter_func(self):
     qs = Category.objects.filter(pk__in=applicable_categories(self.user))
     lookup_var = self.get_lookup_kwarg()
     for cat in user_category_filter(qs, self.user):
         link = ( cat, {lookup_var: cat.pk})
         self.links.append(link)
     return True
Beispiel #5
0
    def get_queryset(self):
        user = self.form._magic_user
        if not hasattr(self, '_queryset'):
            if self.queryset is not None:
                qs = self.queryset
            else:
                qs = self.model._default_manager.get_query_set()
            # category based permissions
            if not user.is_superuser:
                category_fk = model_category_fk(self.model)
                if category_fk:
                    # in ListingInlineOptions: self.instance .. Placement instance, self.model .. Listing
                    view_perm = get_permission('view', self.model)
                    change_perm = get_permission('change', self.model)
                    perms = (
                        view_perm,
                        change_perm,
                    )
                    qs = permission_filtered_model_qs(qs, user, perms)
            # user filtered categories
            qs = utils.user_category_filter(qs, user)

            if self.max_num > 0:
                self._queryset = qs[:self.max_num]
            else:
                self._queryset = qs
        return self._queryset
Beispiel #6
0
def category_field_filter(fspec):
    qs = Category.objects.filter(pk__in=applicable_categories(fspec.user))
    for cat in user_category_filter(qs, fspec.user):
        lookup_var = '%s__%s__exact' % (fspec.f.name, fspec.f.rel.to._meta.pk.name)
        link = ( cat, {lookup_var: cat.pk})
        fspec.links.append(link)
    return True
Beispiel #7
0
 def get_queryset(self):
     # Avoid a circular import.
     from django.contrib.contenttypes.models import ContentType
     user = self.form._magic_user
     if self.instance is None:
         return self.model._default_manager.empty()
     out = self.model._default_manager.filter(
         **{
             self.ct_field.name:
             ContentType.objects.get_for_model(self.instance),
             self.ct_fk_field.name:
             self.instance.pk,
         })
     if user.is_superuser:
         return out
     # filtering -- view permitted categories only
     cfield = model_category_fk_value(self.model)
     if not cfield:
         return out
     # self.instance .. Article, self.model .. Placement (in GenericInlineFormSet for Placement Inline)
     view_perm = get_permission('view', self.model)
     change_perm = get_permission('change', self.model)
     perms = (
         view_perm,
         change_perm,
     )
     qs = permission_filtered_model_qs(out, user, perms)
     qs = utils.user_category_filter(qs, user)
     return qs
Beispiel #8
0
def category_field_filter(fspec):
    #qs = Category.objects.filter(pk__in=applicable_categories(fspec.user))
    print 'Categories %d' % fspec.model_admin.queryset(fspec.request).count()
    #print 'self.params %s' % fspec.params
    #print 'self.result_list %s' % fspec.result_list
    qs = Category.objects.filter(pk__in=applicable_categories(fspec.user))
    for cat in user_category_filter(qs, fspec.user):
        lookup_var = '%s__%s__exact' % (fspec.field_path, fspec.f.rel.to._meta.pk.name)
        link = ( cat, {lookup_var: cat.pk})
        fspec.links.append(link)
    return True
Beispiel #9
0
 def _get_queryset(self):
     if hasattr(self._queryset, '_newman_filtered'):
         return self._queryset
     view_perm = get_permission('view', self.model)
     change_perm = get_permission('change', self.model)
     perms = (view_perm, change_perm,)
     qs = permission_filtered_model_qs(self._queryset, self.user, perms)
     # user category filter
     qs = utils.user_category_filter(qs, self.user)
     qs._newman_filtered = True #magic variable
     self._set_queryset(qs)
     return self._queryset
Beispiel #10
0
    def newman_index(self, request, extra_context=None):
        def translate_and_upper(text):
            return ugettext(text).upper()

        """
        Displays the main Newman index page, without installed apps.
        """
        data = {'sites': []}
        try:
            data['sites'] = get_user_config(request.user, newman_settings.CATEGORY_FILTER)
        except KeyError:
            data['sites'] = []

        publishable_lookup_fields = {
            'day': 'publish_from__day',
            'month': 'publish_from__month',
            'year': 'publish_from__year'
        }
        site_filter_form = SiteFilterForm(data=data, user=request.user)
        if site_filter_form.sites_count == 1:
            site_filter_form = None
        cts = []
        last_filters = {}
        for model, model_admin in self._registry.items():
            if has_model_list_permission(request.user, model) and model_admin.search_fields:
                ct = ContentType.objects.get_for_model(model)
                cts.append(ct)
                # Load saved filter configurations for changelists
                key = 'filter__%s__%s' % (ct.app_label, ct.model)
                last_filter = AdminSetting.objects.filter(var=key, user=request.user)
                if last_filter:
                    last_filters[key] = '?%s' % json_decode(last_filter[0].value)

        future_qs = Placement.objects.select_related().filter(publish_from__gt=datetime.datetime.now()).order_by('publish_from', 'category__tree_path')
        future_qs_perm = permission_filtered_model_qs(future_qs, request.user)
        future_placements = user_category_filter(future_qs_perm, request.user)

        cts.sort( lambda a, b: cz_compare(translate_and_upper(a.name), translate_and_upper(b.name)) )
        context = {
            'title': _('Site administration'),
            'site_filter_form': site_filter_form,
            'searchable_content_types': cts,
            'last_filters': last_filters,
            'future_placements': future_placements,
            'publishable_lookup_fields': publishable_lookup_fields,
            'show_calendar': has_model_list_permission(request.user, Publishable),
        }
        context.update(extra_context or {})
        return render_to_response('newman/newman-index.html', context,
            context_instance=template.RequestContext(request)
        )
Beispiel #11
0
 def _get_queryset(self):
     if hasattr(self._queryset, '_newman_filtered'):
         return self._queryset
     view_perm = get_permission('view', self.model)
     change_perm = get_permission('change', self.model)
     perms = (
         view_perm,
         change_perm,
     )
     qs = permission_filtered_model_qs(self._queryset, self.user, perms)
     # user category filter
     qs = utils.user_category_filter(qs, self.user)
     qs._newman_filtered = True  #magic variable
     self._set_queryset(qs)
     return self._queryset
Beispiel #12
0
    def queryset(self, request):
        """
        First semi-working draft of category-based permissions. It will allow permissions to be set per category
        effectively hiding the content the user has no permission to see/change.
        """
        # return cached queryset, if possible
        if self._cached_queryset_request_id == id(request) and type(
                self._cached_queryset) != type(None):
            return self._cached_queryset

        q = super(NewmanModelAdmin, self).queryset(request)
        # user category filter
        qs = utils.user_category_filter(q, request.user)

        # if self.model is licensed filter queryset
        if License._meta.installed:
            exclude_pks = License.objects.unapplicable_for_model(self.model)
            qs_tmp = qs.exclude(pk__in=exclude_pks)
            utils.copy_queryset_flags(qs_tmp, qs)
            qs = qs_tmp

        if request.user.is_superuser:
            return qs
        view_perm = self.opts.app_label + '.' + 'view_' + self.model._meta.module_name.lower(
        )
        change_perm = self.opts.app_label + '.' + 'change_' + self.model._meta.module_name.lower(
        )
        perms = (
            view_perm,
            change_perm,
        )
        #        return permission_filtered_model_qs(qs, request.user, perms)
        qs_tmp = permission_filtered_model_qs(qs, request.user, perms)
        utils.copy_queryset_flags(qs_tmp, qs)

        # cache the result
        self._cached_queryset_request_id = id(request)
        self._cached_queryset = qs_tmp
        return qs_tmp
Beispiel #13
0
 def get_queryset(self):
     # Avoid a circular import.
     from django.contrib.contenttypes.models import ContentType
     user = self.form._magic_user
     if self.instance is None:
         return self.model._default_manager.empty()
     out = self.model._default_manager.filter(**{
         self.ct_field.name: ContentType.objects.get_for_model(self.instance),
         self.ct_fk_field.name: self.instance.pk,
     })
     if user.is_superuser:
         return out
     # filtering -- view permitted categories only
     cfield = model_category_fk_value(self.model)
     if not cfield:
         return out
     # self.instance .. Article, self.model .. Placement (in GenericInlineFormSet for Placement Inline)
     view_perm = get_permission('view', self.model)
     change_perm = get_permission('change', self.model)
     perms = (view_perm, change_perm,)
     qs = permission_filtered_model_qs(out, user, perms)
     qs = utils.user_category_filter(qs, user)
     return qs
Beispiel #14
0
    def get_queryset(self):
        user = self.form._magic_user
        if not hasattr(self, '_queryset'):
            if self.queryset is not None:
                qs = self.queryset
            else:
                qs = self.model._default_manager.get_query_set()
            # category based permissions
            if not user.is_superuser:
                category_fk = model_category_fk(self.model)
                if category_fk:
                    # in ListingInlineOptions: self.instance .. Placement instance, self.model .. Listing
                    view_perm = get_permission('view', self.model)
                    change_perm = get_permission('change', self.model)
                    perms = (view_perm, change_perm,)
                    qs = permission_filtered_model_qs(qs, user, perms)
            # user filtered categories
            qs = utils.user_category_filter(qs, user)

            if self.max_num > 0:
                self._queryset = qs[:self.max_num]
            else:
                self._queryset = qs
        return self._queryset
Beispiel #15
0
    def suggest_view(self, request, extra_context=None):
        self.register_newman_variables(request)

        SUGGEST_VIEW_LIMIT = getattr(settings, 'SUGGEST_VIEW_LIMIT', 20)
        SUGGEST_VIEW_MIN_LENGTH = getattr(settings, 'SUGGEST_VIEW_MIN_LENGTH', 2)

        if not ('f' in request.GET.keys() and 'q' in request.GET.keys()):
            raise AttributeError, 'Invalid query attributes. Example: ".../?f=field_a&f=field_b&q=search_term&o=offset"'
        elif len(request.GET.get('q')) < SUGGEST_VIEW_MIN_LENGTH:
            return HttpResponse( '', mimetype='text/plain;charset=utf-8' )

        offset = 0
        if 'o' in request.GET.keys() and request.GET.get('o'):
            offset = int(request.GET.get('o'))
        limit = offset + SUGGEST_VIEW_LIMIT

        model_fields = [mf.name for mf in self.model._meta.fields]
        lookup_fields = []
        lookup_value = request.GET.get('q')
        lookup = None
        has_non_lookup_attr = False
        all_fields = [u'id'] + request.GET.getlist('f')

        for lf in all_fields:
            if lf in model_fields or lf.split('__')[0] in model_fields:
                lookup_fields.append(lf)
            elif hasattr(self.model, lf):
                has_non_lookup_attr = True
            else:
                raise AttributeError, 'Model "%s" has not field "%s". Possible fields are "%s".' \
                                    % (self.model._meta.object_name, lf, ', '.join(model_fields))

        for f in lookup_fields:
            lookup_key = str('%s__icontains' % f)
            if not lookup:
                lookup = models.Q(**{lookup_key: lookup_value})
            else:
                lookup = lookup | models.Q(**{lookup_key: lookup_value})
        # user role based category filtering
        if not is_category_model(self.model):
            category_field = model_category_fk(self.model)
            if category_field and request.user:
                applicable = applicable_categories(request.user)
                args_lookup = { '%s__in' % category_field.name: applicable}
                lookup = lookup & models.Q(**args_lookup)
        else:
            applicable = applicable_categories(request.user)
            lookup = lookup & models.Q(pk__in=applicable)
        # user category filter
        qs = utils.user_category_filter(self.model.objects.filter(lookup), request.user)

        if not has_non_lookup_attr:
            data = qs.values(*lookup_fields)
        else:
            data = qs.only(*lookup_fields)

        def construct_row(inst, fields):
            row = {}
            for f in fields:
                attr = getattr(inst, f)
                if callable(attr):
                    row[f] = attr()
                else:
                    row[f] = attr
                row[f] = truncatewords(striptags(unicode(row[f])), 5)
            return row

        if has_non_lookup_attr:
            outdata = []
            for i in data:
                outdata.append(construct_row(i, all_fields))
            data = outdata

        # sort the suggested items so that those starting with the sought term come first
        def compare(a,b):
            def _cmp(a,b,sought):
                a_starts = unicode(a).lower().startswith(sought)
                b_starts = unicode(b).lower().startswith(sought)
                # if exactly one of (a,b) starts with sought, the one starting with it comes first
                if a_starts ^ b_starts:
                    if a_starts: return -1
                    if b_starts: return +1
                # else compare lexicographically
                return cmp(a,b)
            return _cmp(a,b,unicode(lookup_value).lower())
        cnt = len(data)
        data = list(data)
        if offset >= len(data): return HttpResponse('SPECIAL: OFFSET OUT OF RANGE', mimetype='text/plain')
        data.sort(cmp=compare, key=lambda x: x[lookup_fields[1]])
        data = data[offset:limit]

        ft = []
        ft.append('{cnt:%d}' % cnt)
        for item in data:
            ft.append( "%s".encode('utf-8') % '|'.join("%s" % item[f] for f in all_fields) )

        return HttpResponse( '\n'.join(ft), mimetype='text/plain;charset=utf-8' )
Beispiel #16
0
    def suggest_view(self, request, extra_context=None):
        self.register_newman_variables(request)

        if not ('f' in request.GET.keys() and 'q' in request.GET.keys()):
            raise AttributeError, 'Invalid query attributes. Example: ".../?f=field_a&f=field_b&q=search_term&o=offset"'
        elif len(request.GET.get(
                'q')) < newman_settings.SUGGEST_VIEW_MIN_LENGTH:
            return HttpResponse('', mimetype='text/plain;charset=utf-8')

        offset = 0
        if 'o' in request.GET.keys() and request.GET.get('o'):
            offset = int(request.GET.get('o'))
        limit = offset + newman_settings.SUGGEST_VIEW_LIMIT

        model_fields = [mf.name for mf in self.model._meta.fields]
        lookup_fields = []
        lookup_value = request.GET.get('q')
        lookup = None
        has_non_lookup_attr = False
        all_fields = [u'id'] + request.GET.getlist('f')

        for lf in all_fields:
            if lf in model_fields or lf.split('__')[0] in model_fields:
                lookup_fields.append(lf)
            elif hasattr(self.model, lf):
                has_non_lookup_attr = True
            else:
                raise AttributeError, 'Model "%s" has not field "%s". Possible fields are "%s".' \
                                    % (self.model._meta.object_name, lf, ', '.join(model_fields))

        for f in lookup_fields:
            lookup_key = str('%s__icontains' % f)
            if not lookup:
                lookup = models.Q(**{lookup_key: lookup_value})
            else:
                lookup = lookup | models.Q(**{lookup_key: lookup_value})
        # user role based category filtering
        if not is_category_model(self.model):
            category_field = model_category_fk(self.model)
            if category_field and request.user:
                applicable = applicable_categories(request.user)
                args_lookup = {'%s__in' % category_field.name: applicable}
                lookup = lookup & models.Q(**args_lookup)
        else:
            applicable = applicable_categories(request.user)
            lookup = lookup & models.Q(pk__in=applicable)
        # user category filter
        qs = utils.user_category_filter(self.model.objects.filter(lookup),
                                        request.user)

        if not has_non_lookup_attr:
            data = qs.values(*lookup_fields)
        else:
            data = qs.only(*lookup_fields)

        def construct_row(inst, fields):
            row = {}
            for f in fields:
                attr = getattr(inst, f)
                if callable(attr):
                    row[f] = attr()
                else:
                    row[f] = attr
                row[f] = truncatewords(striptags(unicode(row[f])), 5)
            return row

        if has_non_lookup_attr:
            outdata = []
            for i in data:
                outdata.append(construct_row(i, all_fields))
            data = outdata

        # sort the suggested items so that those starting with the sought term come first
        def compare(a, b):
            def _cmp(a, b, sought):
                a_starts = unicode(a).lower().startswith(sought)
                b_starts = unicode(b).lower().startswith(sought)
                # if exactly one of (a,b) starts with sought, the one starting with it comes first
                if a_starts ^ b_starts:
                    if a_starts: return -1
                    if b_starts: return +1
                # else compare lexicographically
                return cmp(a, b)

            return _cmp(a, b, unicode(lookup_value).lower())

        cnt = len(data)
        data = list(data)
        if offset >= len(data):
            return HttpResponse('SPECIAL: OFFSET OUT OF RANGE',
                                mimetype='text/plain')
        data.sort(cmp=compare, key=lambda x: x[lookup_fields[1]])
        data = data[offset:limit]

        ft = []
        ft.append('{cnt:%d}' % cnt)
        for item in data:
            ft.append("%s".encode('utf-8') % '|'.join("%s" % item[f]
                                                      for f in all_fields))

        return HttpResponse('\n'.join(ft), mimetype='text/plain;charset=utf-8')