Changeset 1725

Show
Ignore:
Timestamp:
07/29/08 14:33:43 (20 months ago)
Author:
JensDiemer
Message:

* merge some redirect code together
* work-a-round for restricted plugin method and settings.TEMPLATE_DEBUG is on.
* add a unittest for this.

Location:
trunk/pylucid
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • trunk/pylucid/PyLucid/index.py

    r1634 r1725  
    2424                                                           HttpResponseRedirect 
    2525from django.conf import settings 
    26 from django.template import RequestContext 
     26from django.template import RequestContext, TemplateSyntaxError 
    2727from django.utils.safestring import mark_safe 
    2828from django.utils.translation import ugettext as _ 
     
    4848) 
    4949 
     50def _redirect_to_login(request): 
     51    """ 
     52    Redirect to the _comment auth login with the default page 
     53    FIXME: We should build the auth command url in a better way. 
     54    """ 
     55    path = "/%s/%s/auth/login/?next=%s" % ( 
     56        settings.COMMAND_URL_PREFIX, Page.objects.default_page.id, request.path 
     57    ) 
     58    return HttpResponseRedirect(path) 
     59 
     60def _redirect_access_denied(request): 
     61    """ 
     62    Redirect to login page, if the user is anonymous. 
     63    """ 
     64    if not request.user.is_anonymous(): 
     65        # The user is logged in. But he hasn't the rights to see the page 
     66        # or run the plugin method 
     67        raise AccessDenied("User can see this page content!") 
     68 
     69    return _redirect_to_login(request) 
     70 
    5071 
    5172def _render_cms_page(request, context, page_content=None): 
     
    7798 
    7899    # Render only the CMS page content: 
    79     page_content = render_string_template(page_content, context) 
     100    try: 
     101        page_content = render_string_template(page_content, context) 
     102        # If a user access a public viewable cms page, but in the page content 
     103        # is a lucidTag witch is a restricted method, the pylucid plugin 
     104        # manager would normaly raise a AccessDenied. 
     105        # The Problem is, if settings.TEMPLATE_DEBUG is on, we didn't get a 
     106        # AccessDenied directly, we always get a TemplateSyntaxError! All 
     107        # other errors will catched and raised a TemplateSyntaxError, too. 
     108        # See django/template/debug.py 
     109        # TODO: Instead of a redirect to the login command, we can insert 
     110        # the ouput from auth.login directly 
     111    except TemplateSyntaxError, err: 
     112        # Check if it was a AccessDenied exception 
     113        # sys.exc_info() added in django/template/debug.py 
     114        error_class = err.exc_info[1] 
     115        if isinstance(error_class, AccessDenied): 
     116            return _redirect_access_denied(request) 
     117        else: 
     118            raise # raise the original error 
     119    except AccessDenied: 
     120        # settings.TEMPLATE_DEBUG is off 
     121        return _redirect_access_denied(request) 
    80122 
    81123    # http://www.djangoproject.com/documentation/templates_python/#filters-and-auto-escaping 
     
    156198    try: 
    157199        current_page_obj = Page.objects.get_by_shortcut(url, request.user) 
    158     except AccessDenied: 
    159         if request.user.is_anonymous(): 
    160             # FIXME: We should build the auth command url in a better way. 
    161             next = '?next=%s' % request.path 
    162             path = '/'.join( 
    163                 ('',settings.COMMAND_URL_PREFIX, 
    164                  str(Page.objects.default_page.id),'auth','login',next) 
    165                 ) 
    166             return HttpResponseRedirect(path) 
    167         else: 
    168             # User is logged in but access is denied, probably due to group restrictions. 
    169             request.user.message_set.create(message=_("Access denied")) 
    170             return HttpResponseRedirect(Page.objects.default_page.get_absolute_url()) 
     200    except Page.DoesNotExist: 
     201        raise Http404(_("Page '%s' doesn't exists.") % url) 
    171202    except Page.objects.WrongShortcut, correct_url: 
    172203        # Some parts of the URL was wrong, but we found a right page 
    173204        # shortcut -> redirect to the right url 
    174205        return HttpResponseRedirect(correct_url) 
    175     except Page.DoesNotExist: 
    176         raise Http404(_("Page '%s' doesn't exists.") % url) 
     206    except AccessDenied: 
     207        if request.user.is_anonymous(): 
     208            # FIXME: We should build the auth command url in a better way. 
     209            return _redirect_to_login(request) 
     210        else: 
     211            # User is logged in but access is denied, 
     212            # probably due to group restrictions. 
     213            request.user.message_set.create(message=_("Access denied")) 
     214            new_url = Page.objects.default_page.get_absolute_url() 
     215            return HttpResponseRedirect(new_url) 
    177216 
    178217    context = _get_context(request, current_page_obj) 
  • trunk/pylucid/tests/test_plugin_api.py

    r1669 r1725  
    6161        ) 
    6262 
    63         self.command = "/%s/%s/%s/%%s/" % ( 
    64             settings.COMMAND_URL_PREFIX, 
    65             self.test_page.id, 
    66             TEST_PLUGIN_NAME, 
    67         ) 
     63        self.base_url = "/%s/%s" % ( # Used with self.assertPluginAccess() 
     64            settings.COMMAND_URL_PREFIX, self.test_page.id 
     65        ) 
     66        self.command = "%s/%s/%%s/" % (self.base_url, TEST_PLUGIN_NAME) 
    6867        self.test_url = self.test_page.get_absolute_url() 
    6968 
     
    332331        ) 
    333332 
     333class PluginPermissionsTest(PluginAPI_Base): 
     334    """ 
     335    Test the permissions of a plugin method 
     336 
     337    Test the work-a-round if settings.TEMPLATE_DEBUG is on and a AccessDenied 
     338    would be catched and raised as a TemplateSyntaxError, see: 
     339     * django/template/debug.py 
     340     * PyLucid.index._render_cms_page() 
     341 
     342    TODO: Must be update if ticket:199 is implemented! 
     343    ticket: "change plugin_manager_data (must_login and must_admin)" 
     344    """ 
     345    def test_restricted_method_deny(self): 
     346        """ 
     347        Test to access a restricted method as a anonymous user. 
     348        Test with settings.TEMPLATE_DEBUG True/False 
     349        """ 
     350        from PyLucid.system.exceptions import AccessDenied 
     351 
     352        def test(): 
     353            try: 
     354                self.assertPluginAccess( 
     355                    self.base_url, 
     356                    plugin_name = TEST_PLUGIN_NAME, 
     357                    method_names = ("test_restricted_method",), 
     358                    must_contain=("[Permission Denied!]",), 
     359                    must_not_contain=("Traceback",) 
     360                ) 
     361            except AccessDenied: 
     362                pass # It's ok. 
     363            except Exception: 
     364                raise 
     365 
     366        self.client.logout() 
     367        old_value = settings.TEMPLATE_DEBUG 
     368 
     369        settings.TEMPLATE_DEBUG = True 
     370        test() 
     371        settings.TEMPLATE_DEBUG = False 
     372        test() 
     373 
     374        settings.TEMPLATE_DEBUG = old_value 
     375 
     376    def test_restricted_method_allowed(self): 
     377        """ 
     378        If the user logged in, he should see the plugin output 
     379        """ 
     380        self.login("superuser") # login client as superuser 
     381        self.assertPluginAccess( 
     382            self.base_url, 
     383            plugin_name = TEST_PLUGIN_NAME, 
     384            method_names = ("test_restricted_method",), 
     385            must_contain=("This is restricted!",), 
     386            must_not_contain=("Traceback",) 
     387        ) 
     388 
    334389 
    335390if __name__ == "__main__": 
  • trunk/pylucid/tests/unittest_plugin/unittest_plugin.py

    r1706 r1725  
    7979        """ 
    8080        self.response.write("Hello world!") 
     81 
     82    def test_restricted_method(self): 
     83        """ 
     84        TODO: Must be update if ticket:199 is implemented! 
     85        ticket: "change plugin_manager_data (must_login and must_admin)" 
     86        """ 
     87        self.response.write("<pre>This is restricted!</pre>") 
    8188 
    8289    def test_attributes(self, attr_name): 
  • trunk/pylucid/tests/unittest_plugin/unittest_plugin_cfg.py

    r1720 r1725  
    5656        "must_admin"    : False, 
    5757    }, 
     58    "test_restricted_method" : global_rights, 
    5859    "test_attributes" : global_rights, 
    5960    "test_page_msg" : global_rights,