Changeset 2527

Show
Ignore:
Timestamp:
02/05/10 08:15:48 (6 weeks ago)
Author:
JensDiemer
Message:

Update Blog plugin:

  • move/merge queryset stuff in model manager.
  • filter tag cloud by site/accessable, too.
  • fix security hole: detail_view doesn't filter the ID. User can access non public entries by manipulate the ID in the url.
Location:
branches/0.9/pylucid_project/pylucid_plugins/blog
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • branches/0.9/pylucid_project/pylucid_plugins/blog/models.py

    r2469 r2527  
    1818 
    1919from django.db import models 
     20from django.conf import settings 
    2021from django.core import urlresolvers 
    2122from django.db.models import signals 
     
    2324from django.template.defaultfilters import slugify 
    2425from django.utils.translation import ugettext_lazy as _ 
     26from django.core.paginator import Paginator, InvalidPage, EmptyPage 
    2527 
    2628# http://code.google.com/p/django-tagging/ 
    2729from tagging.fields import TagField 
    28  
    29 from pylucid_project.pylucid_plugins import update_journal 
    3030 
    3131from pylucid_project.apps.pylucid.shortcuts import failsafe_message 
     
    3535from pylucid_project.apps.pylucid.cache import clean_complete_pagecache 
    3636 
     37from pylucid_project.pylucid_plugins import update_journal 
     38 
     39from pylucid_project.pylucid_plugins.blog.preference_forms import BlogPrefForm 
     40 
     41# from django-tagging 
     42from tagging.models import Tag 
     43 
    3744 
    3845TAG_INPUT_HELP_URL = \ 
    3946"http://google.com/search?q=cache:django-tagging.googlecode.com/files/tagging-0.2-overview.html#tag-input" 
     47 
     48 
     49class BlogEntryManager(models.Manager): 
     50    def all_accessible(self, request): 
     51        """ returns a queryset of all blog entries that the current user can access. """ 
     52        filters = self.get_filters(request) 
     53        return self.model.objects.filter(**filters) 
     54 
     55    def get_filters(self, request): 
     56        """ 
     57        Construct queryset filter kwargs, to limit the BlogEntry queryset for the current user 
     58        """ 
     59        current_lang = request.PYLUCID.language_entry 
     60 
     61        filters = { 
     62            "sites__id__exact": settings.SITE_ID, 
     63            "language": current_lang, 
     64        } 
     65 
     66        if not request.user.has_perm("blog.change_blogentry"): 
     67            filters["is_public"] = True 
     68 
     69        return filters 
     70 
     71    def get_tag_cloud(self, request): 
     72        filters = self.get_filters(request) 
     73        tag_cloud = Tag.objects.cloud_for_model(self.model, steps=2, filters=filters) 
     74        return tag_cloud 
     75 
     76    def paginate(self, request, queryset): 
     77        """ Limit the queryset with django Paginator and returns the Paginator instance """ 
     78        # Get number of entries allowed by the users see on a page.  
     79        pref_form = BlogPrefForm() 
     80        preferences = pref_form.get_preferences() 
     81        if request.user.is_anonymous(): 
     82            max_count = preferences.get("max_anonym_count", 10) 
     83        else: 
     84            max_count = preferences.get("max_user_count", 30) 
     85 
     86        # Show max_count entries per page 
     87        paginator = Paginator(queryset, max_count) 
     88 
     89        # Make sure page request is an int. If not, deliver first page. 
     90        try: 
     91            page = int(request.GET.get('page', '1')) 
     92        except ValueError: 
     93            page = 1 
     94 
     95        # If page request (9999) is out of range, deliver last page of results. 
     96        try: 
     97            return paginator.page(page) 
     98        except (EmptyPage, InvalidPage): 
     99            return paginator.page(paginator.num_pages) 
     100 
    40101 
    41102 
     
    55116        lastupdateby   -> ForeignKey to user who has edited this entry 
    56117    """ 
     118    objects = BlogEntryManager() 
     119 
    57120    headline = models.CharField(_('Headline'), 
    58121        help_text=_("The blog entry headline"), max_length=255 
  • branches/0.9/pylucid_project/pylucid_plugins/blog/views.py

    r2526 r2527  
    3030from django.views.decorators.csrf import csrf_protect 
    3131from django.contrib.comments.views.comments import post_comment 
    32 from django.core.paginator import Paginator, InvalidPage, EmptyPage 
    3332 
    3433from pylucid_project.apps.pylucid.decorators import render_to 
    3534 
    3635from pylucid_project.pylucid_plugins.blog.models import BlogEntry 
    37 from pylucid_project.pylucid_plugins.blog.preference_forms import BlogPrefForm 
    3836 
    3937# from django-tagging 
    4038from tagging.models import Tag, TaggedItem 
    4139 
    42  
    43 def _get_filters(request): 
    44     """ 
    45     Construct queryset filter. 
    46     Used for blog entry filtering and for Tag.objects.cloud_for_model() 
    47     """ 
    48     current_lang = request.PYLUCID.language_entry 
    49     filters = {"language":current_lang} 
    50  
    51     if not request.user.has_perm("blog.change_blogentry"): 
    52         filters["is_public"] = True 
    53  
    54     return filters 
    55  
    56  
    57 def _filter_blog_entries(request, queryset): 
    58     filters = _get_filters(request) 
    59     queryset = queryset.filter(**filters) 
    60     return queryset 
    61  
    62  
    63 def _paginat_queryset(request, queryset): 
    64     # Get number of entries allowed by the users see on a page.  
    65     pref_form = BlogPrefForm() 
    66     preferences = pref_form.get_preferences() 
    67     if request.user.is_anonymous(): 
    68         max_count = preferences.get("max_anonym_count", 10) 
    69     else: 
    70         max_count = preferences.get("max_user_count", 30) 
    71  
    72     # Show max_count entries per page 
    73     paginator = Paginator(queryset, max_count) 
    74  
    75     # Make sure page request is an int. If not, deliver first page. 
    76     try: 
    77         page = int(request.GET.get('page', '1')) 
    78     except ValueError: 
    79         page = 1 
    80  
    81     # If page request (9999) is out of range, deliver last page of results. 
    82     try: 
    83         return paginator.page(page) 
    84     except (EmptyPage, InvalidPage): 
    85         return paginator.page(paginator.num_pages) 
    86  
    87  
    88 def _get_tag_cloud(request): 
    89     filters = _get_filters(request) 
    90     tag_cloud = Tag.objects.cloud_for_model(BlogEntry, steps=2, filters=filters) 
    91     return tag_cloud 
    9240 
    9341 
     
    10654    """ 
    10755    # Get all blog entries, that the current user can see 
    108     queryset = BlogEntry.on_site 
    109     queryset = _filter_blog_entries(request, queryset) 
     56    queryset = BlogEntry.objects.all_accessible(request) 
    11057 
    111     entries = _paginat_queryset(request, queryset) 
     58    # Limit the queryset with django Paginator 
     59    paginator = BlogEntry.objects.paginate(request, queryset) 
     60 
     61    tag_cloud = BlogEntry.objects.get_tag_cloud(request) 
    11262 
    11363    context = { 
    114         "entries": entries, 
    115         "tag_cloud": _get_tag_cloud(request), 
     64        "entries": paginator, 
     65        "tag_cloud": tag_cloud, 
    11666        "CSS_PLUGIN_CLASS_NAME": settings.PYLUCID.CSS_PLUGIN_CLASS_NAME, 
    11767    } 
     
    12575    """ 
    12676    tags = tag.strip("/").split("/") 
    127     queryset = TaggedItem.objects.get_by_model(BlogEntry, tags) 
    128     queryset = _filter_blog_entries(request, queryset) 
    12977 
    130     entries = _paginat_queryset(request, queryset) 
     78    # Get all blog entries, that the current user can see 
     79    queryset = BlogEntry.objects.all_accessible(request) 
     80 
     81    queryset = TaggedItem.objects.get_by_model(queryset, tags) 
     82 
     83    # Limit the queryset with django Paginator 
     84    paginator = BlogEntry.objects.paginate(request, queryset) 
    13185 
    13286    # Add link to the breadcrumbs ;) 
    13387    _add_breadcrumb(request, title=_("All '%s' tagged items" % ",".join(tags)), url=request.path) 
    13488 
     89    tag_cloud = BlogEntry.objects.get_tag_cloud(request) 
     90 
    13591    context = { 
    136         "entries": entries, 
    137         "tag_cloud": _get_tag_cloud(request), 
     92        "entries": paginator, 
     93        "tag_cloud": tag_cloud, 
    13894        "CSS_PLUGIN_CLASS_NAME": settings.PYLUCID.CSS_PLUGIN_CLASS_NAME, 
    13995    } 
     
    144100@render_to("blog/detail_view.html") 
    145101def detail_view(request, id, title): 
    146     entry = BlogEntry.objects.get(pk=id) 
     102    """ 
     103    Display one blog entry with a comment form. 
     104    """ 
     105    # Get all blog entries, that the current user can see 
     106    queryset = BlogEntry.objects.all_accessible(request) 
     107 
     108    try: 
     109        entry = queryset.get(pk=id) 
     110    except BlogEntry.DoesNotExist: 
     111        msg = "Blog entry doesn't exist." 
     112        if settings.DEBUG or request.user.is_staff: 
     113            msg += " (ID %r wrong.)" % id 
     114        request.page_msg.error(msg) 
     115        return summary(request) 
    147116 
    148117    # Add link to the breadcrumbs ;) 
     
    154123        return post_comment(request, next=entry.get_absolute_url()) 
    155124 
     125    tag_cloud = BlogEntry.objects.get_tag_cloud(request) 
     126 
    156127    context = { 
    157128        "page_title": entry.headline, # Change the global title with blog headline 
    158129        "entry": entry, 
    159         "tag_cloud": _get_tag_cloud(request), 
     130        "tag_cloud": tag_cloud, 
    160131        "CSS_PLUGIN_CLASS_NAME": settings.PYLUCID.CSS_PLUGIN_CLASS_NAME, 
    161132    }