from blog.models import Post from django.contrib.auth.models import User, Permission from django.shortcuts import get_object_or_404 from django.template import Template, Context from django.test import TestCase from django.test.client import RequestFactory from django.urls import reverse from djadmin2.permissions import TemplatePermissionChecker from djadmin2.site import djadmin2_site from djadmin2.types import ModelAdmin2 class TemplatePermissionTest(TestCase): def setUp(self): self.factory = RequestFactory() self.user = User( username='admin', is_staff=True) self.user.set_password('admin') self.user.save() def render(self, template, context): template = Template(template) context = Context(context) return template.render(context) def test_permission_wrapper(self): model_admin = ModelAdmin2(Post, djadmin2_site) request = self.factory.get(reverse('admin2:blog_post_index')) request.user = self.user permissions = TemplatePermissionChecker(request, model_admin) context = { 'permissions': permissions, } result = self.render( '{{ permissions.has_unvalid_permission }}', context) self.assertEqual(result, '') result = self.render('{{ permissions.has_add_permission }}', context) self.assertEqual(result, 'False') post_add_permission = Permission.objects.get( content_type__app_label='blog', content_type__model='post', codename='add_post') self.user.user_permissions.add(post_add_permission) # invalidate the users permission cache self.user = get_object_or_404(User, pk=self.user.id) request.user = self.user result = self.render('{{ permissions.has_add_permission }}', context) self.assertEqual(result, 'True') def test_admin_traversal_by_name(self): post_add_permission = Permission.objects.get( content_type__app_label='blog', content_type__model='post', codename='add_post') self.user.user_permissions.add(post_add_permission) model_admin = ModelAdmin2(Post, djadmin2_site) request = self.factory.get(reverse('admin2:blog_post_index')) request.user = self.user permissions = TemplatePermissionChecker(request, model_admin) context = { 'permissions': permissions, } result = self.render('{{ permissions.has_add_permission }}', context) self.assertEqual(result, 'True') result = self.render('{{ permissions.blog_post.has_add_permission }}', context) self.assertEqual(result, 'True') result = self.render('{{ permissions.blog_post.has_change_permission }}', context) self.assertEqual(result, 'False') result = self.render('{{ permissions.auth_user.has_delete_permission }}', context) self.assertEqual(result, 'False') result = self.render( '{{ permissions.unknown_app.has_add_permission }}', context) self.assertEqual(result, '') result = self.render( '{{ permissions.blog_post.has_unvalid_permission }}', context) self.assertEqual(result, '') def test_admin_binding(self): user_admin = djadmin2_site.get_admin_by_name('auth_user') post_admin = djadmin2_site.get_admin_by_name('blog_post') request = self.factory.get(reverse('admin2:auth_user_index')) request.user = self.user permissions = TemplatePermissionChecker(request, user_admin) post = Post.objects.create(title='Hello', body='world') context = { 'post': post, 'post_admin': post_admin, 'permissions': permissions, } result = self.render( '{% load admin2_tags %}' '{{ permissions|for_admin:post_admin }}', context) self.assertEqual(result, '') result = self.render( '{% load admin2_tags %}' '{{ permissions.has_add_permission }}' '{% with permissions|for_admin:post_admin as permissions %}' '{{ permissions.has_add_permission }}' '{% endwith %}', context) self.assertEqual(result, 'FalseFalse') post_add_permission = Permission.objects.get( content_type__app_label='blog', content_type__model='post', codename='add_post') self.user.user_permissions.add(post_add_permission) # invalidate the users permission cache self.user = get_object_or_404(User, pk=self.user.id) request.user = self.user result = self.render( '{% load admin2_tags %}' '{{ permissions.has_add_permission }}' '{% with permissions|for_admin:post_admin as permissions %}' '{{ permissions.has_add_permission }}' '{% endwith %}' '{{ permissions.blog_post.has_add_permission }}', context) self.assertEqual(result, 'FalseTrueTrue') # giving a string (the name of the admin) also works result = self.render( '{% load admin2_tags %}' '{% with permissions|for_admin:"blog_post" as permissions %}' '{{ permissions.has_add_permission }}' '{% endwith %}', context) self.assertEqual(result, 'True') # testing invalid admin names result = self.render( '{% load admin2_tags %}' '{% with permissions|for_admin:"invalid_admin_name" as permissions %}' '{{ permissions.has_add_permission }}' '{% endwith %}', context) self.assertEqual(result, '') def test_view_binding(self): user_admin = djadmin2_site.get_admin_by_name('auth_user') post_admin = djadmin2_site.get_admin_by_name('blog_post') request = self.factory.get(reverse('admin2:auth_user_index')) request.user = self.user permissions = TemplatePermissionChecker(request, user_admin) context = { 'post_admin': post_admin, 'post_add_view': post_admin.create_view, 'permissions': permissions, } result = self.render( '{% load admin2_tags %}' '{{ permissions|for_view:"add" }}', context) self.assertEqual(result, 'False') # view classes are not supported yet result = self.render( '{% load admin2_tags %}' '{{ permissions|for_view:post_add_view }}', context) self.assertEqual(result, '') result = self.render( '{% load admin2_tags %}' # user add permission '{{ permissions.has_add_permission }}' '{% with permissions|for_admin:"blog_post"|for_view:"add" as post_add_perm %}' # post add permission '{{ post_add_perm }}' '{% endwith %}', context) self.assertEqual(result, 'FalseFalse') post_add_permission = Permission.objects.get( content_type__app_label='blog', content_type__model='post', codename='add_post') self.user.user_permissions.add(post_add_permission) user_change_permission = Permission.objects.get( content_type__app_label='auth', content_type__model='user', codename='change_user') self.user.user_permissions.add(user_change_permission) # invalidate the users permission cache self.user = get_object_or_404(User, pk=self.user.id) request.user = self.user result = self.render( '{% load admin2_tags %}' # user add permission '{{ permissions.has_add_permission }}' '{% with permissions|for_admin:"blog_post"|for_view:"add" as post_add_perm %}' # post add permission '{{ post_add_perm }}' '{% endwith %}' # user change permission '{{ permissions|for_view:"change" }}', context) self.assertEqual(result, 'FalseTrueTrue') # giving a string (the name of the view) also works result = self.render( '{% load admin2_tags %}' '{% with permissions|for_view:"change" as user_change_perm %}' '1{{ user_change_perm }}' '2{{ user_change_perm|for_view:"add" }}' # this shouldn't return True or False but '' since the # previously bound change view doesn't belong to the newly # bound blog_post admin '3{{ user_change_perm|for_admin:"blog_post" }}' '4{{ user_change_perm|for_admin:"blog_post"|for_view:"add" }}' '{% endwith %}', context) self.assertEqual(result, '1True2False34True') def test_object_level_permission(self): model_admin = ModelAdmin2(Post, djadmin2_site) request = self.factory.get(reverse('admin2:blog_post_index')) request.user = self.user permissions = TemplatePermissionChecker(request, model_admin) post = Post.objects.create(title='Hello', body='world') context = { 'post': post, 'permissions': permissions, } result = self.render( '{% load admin2_tags %}' '{{ permissions.has_unvalid_permission|for_object:post }}', context) self.assertEqual(result, '') result = self.render( '{% load admin2_tags %}' '{{ permissions.has_add_permission|for_object:post }}', context) self.assertEqual(result, 'False') post_add_permission = Permission.objects.get( content_type__app_label='blog', content_type__model='post', codename='add_post') self.user.user_permissions.add(post_add_permission) # invalidate the users permission cache self.user = get_object_or_404(User, pk=self.user.id) request.user = self.user # object level permission are not supported by default. So this will # return ``False``. result = self.render( '{% load admin2_tags %}' '{{ permissions.has_add_permission }}' '{{ permissions.has_add_permission|for_object:post }}', context) self.assertEqual(result, 'TrueFalse') # binding an object and then checking for a specific view also works result = self.render( '{% load admin2_tags %}' '{{ permissions.has_add_permission }}' '{% with permissions|for_object:post as permissions %}' '{{ permissions.has_add_permission }}' '{% endwith %}', context) self.assertEqual(result, 'TrueFalse') class ViewPermissionTest(TestCase): def test_view_permission_was_created(self): permissions = Permission.objects.filter( content_type__app_label='blog', content_type__model='post') self.assertEqual(len(permissions.filter(codename='view_post')), 1)