# HG changeset patch -- Bitbucket.org # Project django-modelviews # URL http://bitbucket.org/david/django-modelviews/overview # User David Larlet # Date 1213912947 -7200 # Node ID 7bb34b38501f7b768aa7d04ab57904880e32f3e7 # Parent 7a46edcc917aa4937d949991024d1904d3301de0 Draft of authentication, still hesitating between dictionaries vs. decorators --- a/tests/test_modelview/tests.py +++ b/tests/test_modelview/tests.py @@ -1,6 +1,7 @@ from django.test import TestCase from models import Article from django.utils import simplejson +from django.contrib.auth.models import User from xml.dom.minidom import parseString @@ -19,7 +20,7 @@ class ModelViewTest(TestCase): Article.objects.create(name="My Story", slug="my-story", body="My thrilling story!") - + User.objects.create_user('david', 'foo@bar.com', 'baz') def test_restricting_exposed_methods(self): """ @@ -28,9 +29,7 @@ class ModelViewTest(TestCase): all other http methods. """ a = Article.objects.all()[0] - response = self.client.post('/articles/', {'name': "Not allowed article", - 'slug': "not-allowed-article", - 'body': "some not allowed text"}) + response = self.client.post('/articles/', {}) self.assertEqual(response.status_code, 405) # no explicit way to send DELETE or PUT methods, so get # a bit sneaky here. @@ -42,6 +41,17 @@ class ModelViewTest(TestCase): self.assertEqual(response.status_code, 405) + def test_restricting_authentication(self): + u = User.objects.all()[0] + response = self.client.get('/auth-articles/') + self.assertEqual(response.status_code, 405) + response = self.client.post('/auth-articles/', {}) + self.assertEqual(response.status_code, 405) + response = self.client.login(username='david', password='baz') + response = self.client.get('/auth-articles/') + self.assertEqual(response.status_code, 200) + + def test_default_responder(self): a = Article.objects.all()[0] response = self.client.get('/articles/%s/' % a.slug) --- a/tests/settings.py +++ b/tests/settings.py @@ -24,9 +24,9 @@ TEMPLATE_LOADERS = ( ) MIDDLEWARE_CLASSES = ( -# 'django.middleware.common.CommonMiddleware', -# 'django.contrib.sessions.middleware.SessionMiddleware', -# 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', # 'django.middleware.doc.XViewMiddleware', ) @@ -39,8 +39,8 @@ TEMPLATE_DIRS = ( INSTALLED_APPS = ( 'django_modelview.generic', 'django_modelview.tests.test_modelview', -# 'django.contrib.auth', -# 'django.contrib.contenttypes', -# 'django.contrib.sessions', -# 'django.contrib.sites', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', ) --- a/tests/urls.py +++ b/tests/urls.py @@ -10,6 +10,9 @@ articles = ModelView(Article.objects.all rw_articles = ModelView(Article.objects.all(), responders=(HtmlResponder,), methods=('GET', 'POST', 'PUT', 'DELETE')) +auth_articles = ModelView(Article.objects.all(), + responders=(HtmlResponder,), + methods={'GET': django_authentication}) formats = '(?P(html|json|xml|yaml|atom|rss))?/?' slug = '(?P[-\w]+)?/?' @@ -18,4 +21,5 @@ urlpatterns = patterns('', ('^articles/%(formats)s$' % locals(), articles), ('^articles/%(slug)s%(formats)s$' % locals(), articles), ('^rw-articles/%(slug)s$' % locals(), rw_articles), + ('^auth-articles/%(slug)s$' % locals(), auth_articles), ) --- a/generic/rest_views.py +++ b/generic/rest_views.py @@ -12,6 +12,10 @@ try: except ImportError: from compatability import BaseDetailView +def django_authentication(request, **kwargs): + return request.user.is_authenticated() + + class BaseResponder(object): def __init__(self, queryset): self.queryset = queryset @@ -314,11 +318,14 @@ class ModelView(BaseDetailView): self.paginate_by = paginate_by self.allow_empty = allow_empty self.responders = dict((responder.__name__, responder) for responder in responders) - self.methods = methods + if isinstance(methods, tuple): + self.methods = dict(zip(methods, len(methods)*(False,))) + else: + self.methods = methods super(ModelView, self).__init__(queryset, slug_field) - def __call__(self, request, object_pk=None, slug=None, format='html'): + def __call__(self, request, object_pk=None, slug=None, format='html', **kwargs): """ Redirects to one of the CRUD methods depending on the HTTP method of the request. Checks whether the requested method is allowed for this @@ -326,8 +333,11 @@ class ModelView(BaseDetailView): """ # Restrict request_method = request.method.upper() - if request_method not in self.methods: + if request_method not in self.methods.keys(): return HttpResponseNotAllowed(request_method) + if self.methods[request_method]: + if not self.methods[request_method](request, **kwargs): + return HttpResponseNotAllowed(request_method) # Unmatched regex groups in the url will not recieve # the default value specified for the method, but