diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
old mode 100644
new mode 100755
index 9bb9f4a..d10230f
|
a
|
b
|
class AdminSite(object):
|
| 293 | 293 | This should *not* assume the user is already logged in. |
| 294 | 294 | """ |
| 295 | 295 | from django.contrib.auth.views import logout |
| 296 | | defaults = { |
| 297 | | 'current_app': self.name, |
| 298 | | 'extra_context': extra_context or {}, |
| 299 | | } |
| 300 | | if self.logout_template is not None: |
| 301 | | defaults['template_name'] = self.logout_template |
| 302 | | return logout(request, **defaults) |
| | 296 | |
| | 297 | if request.method == "POST": |
| | 298 | defaults = { |
| | 299 | 'current_app': self.name, |
| | 300 | 'extra_context': extra_context or {}, |
| | 301 | } |
| | 302 | |
| | 303 | if self.logout_template is not None: |
| | 304 | defaults['template_name'] = self.logout_template |
| | 305 | |
| | 306 | return logout(request, **defaults) |
| | 307 | else: |
| | 308 | context = { |
| | 309 | 'title' : _('Are you sure?'), |
| | 310 | } |
| | 311 | return TemplateResponse(request, 'admin/logout_confirmation.html', context) |
| | 312 | |
| 303 | 313 | |
| 304 | 314 | @never_cache |
| 305 | 315 | def login(self, request, extra_context=None): |
diff --git a/django/contrib/admin/templates/admin/base.html b/django/contrib/admin/templates/admin/base.html
old mode 100644
new mode 100755
index 4b3c429..4482bb8
|
a
|
b
|
|
| 7 | 7 | <!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="{% block stylesheet_ie %}{% static "admin/css/ie.css" %}{% endblock %}" /><![endif]--> |
| 8 | 8 | {% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% static "admin/css/rtl.css" %}{% endblock %}" />{% endif %} |
| 9 | 9 | <script type="text/javascript">window.__admin_media_prefix__ = "{% filter escapejs %}{% static "admin/" %}{% endfilter %}";</script> |
| | 10 | <script type="text/javascript" src="{% static "admin/js/jquery.min.js" %}"></script> |
| | 11 | <script type="text/javascript" src="{% static "admin/js/jquery.init.js" %}"></script> |
| | 12 | <script id="admin-logout-template" defer type="text/html"> |
| | 13 | <form id="logout-form" action="{% url 'admin:logout' %}" method="post">{% csrf_token %}</form> |
| | 14 | </script> |
| | 15 | <script type="text/javascript"> |
| | 16 | (function($) { |
| | 17 | $(document).ready(function() { |
| | 18 | $('a[href="{% url 'admin:logout' %}"]').click(function(ev) { |
| | 19 | ev.preventDefault(); |
| | 20 | $('body').append($('#admin-logout-template').html()); |
| | 21 | $('#logout-form').submit(); |
| | 22 | }); |
| | 23 | }); |
| | 24 | })(django.jQuery); |
| | 25 | </script> |
| | 26 | |
| 10 | 27 | {% block extrahead %}{% endblock %} |
| 11 | 28 | {% block blockbots %}<meta name="robots" content="NONE,NOARCHIVE" />{% endblock %} |
| 12 | 29 | </head> |
diff --git a/django/contrib/admin/templates/admin/logout_confirmation.html b/django/contrib/admin/templates/admin/logout_confirmation.html
new file mode 100755
index 0000000..17f08c5
|
-
|
+
|
|
| | 1 | {% extends "admin/base_site.html" %} |
| | 2 | {% load i18n %} |
| | 3 | |
| | 4 | {% block breadcrumbs %} |
| | 5 | <div class="breadcrumbs"> |
| | 6 | <a href="../">{% trans "Home" %}</a> › |
| | 7 | </div> |
| | 8 | {% endblock %} |
| | 9 | |
| | 10 | |
| | 11 | |
| | 12 | {% block content %} |
| | 13 | <p>{% blocktrans %}Are you sure you want to logout?{% endblocktrans %}</p> |
| | 14 | <form action="" method="post"> |
| | 15 | {% csrf_token %} |
| | 16 | <div> |
| | 17 | <input type="hidden" name="post" value="yes" /> |
| | 18 | <input type="submit" value="{% trans "Yes, I'm sure" %}" /> |
| | 19 | </div> |
| | 20 | </form> |
| | 21 | {% endblock %} |
| | 22 | No newline at end of file |
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
old mode 100644
new mode 100755
index 22b65a6..348e2af
|
a
|
b
|
class CustomModelAdminTest(AdminViewBasicTest):
|
| 618 | 618 | self.assertTrue('Hello from a custom login template' in request.content) |
| 619 | 619 | |
| 620 | 620 | def testCustomAdminSiteLogoutTemplate(self): |
| 621 | | request = self.client.get('/test_admin/admin2/logout/') |
| | 621 | request = self.client.post('/test_admin/admin2/logout/') |
| 622 | 622 | self.assertIsInstance(request, TemplateResponse) |
| 623 | 623 | self.assertTemplateUsed(request, 'custom_admin/logout.html') |
| 624 | 624 | self.assertTrue('Hello from a custom logout template' in request.content) |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 745 | 745 | login = self.client.post('/test_admin/admin/', self.super_login) |
| 746 | 746 | self.assertRedirects(login, '/test_admin/admin/') |
| 747 | 747 | self.assertFalse(login.context) |
| 748 | | self.client.get('/test_admin/admin/logout/') |
| | 748 | self.client.post('/test_admin/admin/logout/') |
| 749 | 749 | |
| 750 | 750 | # Test if user enters e-mail address |
| 751 | 751 | request = self.client.get('/test_admin/admin/') |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 767 | 767 | login = self.client.post('/test_admin/admin/', self.adduser_login) |
| 768 | 768 | self.assertRedirects(login, '/test_admin/admin/') |
| 769 | 769 | self.assertFalse(login.context) |
| 770 | | self.client.get('/test_admin/admin/logout/') |
| | 770 | self.client.post('/test_admin/admin/logout/') |
| 771 | 771 | |
| 772 | 772 | # Change User |
| 773 | 773 | request = self.client.get('/test_admin/admin/') |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 775 | 775 | login = self.client.post('/test_admin/admin/', self.changeuser_login) |
| 776 | 776 | self.assertRedirects(login, '/test_admin/admin/') |
| 777 | 777 | self.assertFalse(login.context) |
| 778 | | self.client.get('/test_admin/admin/logout/') |
| | 778 | self.client.post('/test_admin/admin/logout/') |
| 779 | 779 | |
| 780 | 780 | # Delete User |
| 781 | 781 | request = self.client.get('/test_admin/admin/') |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 783 | 783 | login = self.client.post('/test_admin/admin/', self.deleteuser_login) |
| 784 | 784 | self.assertRedirects(login, '/test_admin/admin/') |
| 785 | 785 | self.assertFalse(login.context) |
| 786 | | self.client.get('/test_admin/admin/logout/') |
| | 786 | self.client.post('/test_admin/admin/logout/') |
| 787 | 787 | |
| 788 | 788 | # Regular User should not be able to login. |
| 789 | 789 | request = self.client.get('/test_admin/admin/') |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 828 | 828 | post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict) |
| 829 | 829 | self.assertEqual(post.status_code, 403) |
| 830 | 830 | self.assertEqual(Article.objects.all().count(), 3) |
| 831 | | self.client.get('/test_admin/admin/logout/') |
| | 831 | self.client.post('/test_admin/admin/logout/') |
| 832 | 832 | |
| 833 | 833 | # Add user may login and POST to add view, then redirect to admin root |
| 834 | 834 | self.client.get('/test_admin/admin/') |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 843 | 843 | self.assertEqual(Article.objects.all().count(), 4) |
| 844 | 844 | self.assertEqual(len(mail.outbox), 1) |
| 845 | 845 | self.assertEqual(mail.outbox[0].subject, 'Greetings from a created object') |
| 846 | | self.client.get('/test_admin/admin/logout/') |
| | 846 | self.client.post('/test_admin/admin/logout/') |
| 847 | 847 | |
| 848 | 848 | # Super can add too, but is redirected to the change list view |
| 849 | 849 | self.client.get('/test_admin/admin/') |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 855 | 855 | post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict) |
| 856 | 856 | self.assertRedirects(post, '/test_admin/admin/admin_views/article/') |
| 857 | 857 | self.assertEqual(Article.objects.all().count(), 5) |
| 858 | | self.client.get('/test_admin/admin/logout/') |
| | 858 | self.client.post('/test_admin/admin/logout/') |
| 859 | 859 | |
| 860 | 860 | # 8509 - if a normal user is already logged in, it is possible |
| 861 | 861 | # to change user into the superuser without error |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 883 | 883 | self.assertEqual(request.status_code, 403) |
| 884 | 884 | post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict) |
| 885 | 885 | self.assertEqual(post.status_code, 403) |
| 886 | | self.client.get('/test_admin/admin/logout/') |
| | 886 | self.client.post('/test_admin/admin/logout/') |
| 887 | 887 | |
| 888 | 888 | # change user can view all items and edit them |
| 889 | 889 | self.client.get('/test_admin/admin/') |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 907 | 907 | self.assertEqual(request.status_code, 200) |
| 908 | 908 | self.assertTrue('Please correct the errors below.' in post.content, |
| 909 | 909 | 'Plural error message not found in response to post with multiple errors.') |
| 910 | | self.client.get('/test_admin/admin/logout/') |
| | 910 | self.client.post('/test_admin/admin/logout/') |
| 911 | 911 | |
| 912 | 912 | # Test redirection when using row-level change permissions. Refs #11513. |
| 913 | 913 | RowLevelChangePermissionModel.objects.create(id=1, name="odd id") |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 924 | 924 | request = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', {'name': 'changed'}) |
| 925 | 925 | self.assertEqual(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed') |
| 926 | 926 | self.assertRedirects(request, '/test_admin/admin/') |
| 927 | | self.client.get('/test_admin/admin/logout/') |
| | 927 | self.client.post('/test_admin/admin/logout/') |
| 928 | 928 | for login_dict in [self.joepublic_login, self.no_username_login]: |
| 929 | 929 | self.client.post('/test_admin/admin/', login_dict) |
| 930 | 930 | request = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/') |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 941 | 941 | self.assertEqual(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed') |
| 942 | 942 | self.assertEqual(request.status_code, 200) |
| 943 | 943 | self.assertContains(request, 'login-form') |
| 944 | | self.client.get('/test_admin/admin/logout/') |
| | 944 | self.client.post('/test_admin/admin/logout/') |
| 945 | 945 | |
| 946 | 946 | def testConditionallyShowAddSectionLink(self): |
| 947 | 947 | """ |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 1004 | 1004 | request = self.client.get('/test_admin/admin/admin_views/customarticle/%d/history/' % article_pk) |
| 1005 | 1005 | self.assertTemplateUsed(request, 'custom_admin/object_history.html') |
| 1006 | 1006 | |
| 1007 | | self.client.get('/test_admin/admin/logout/') |
| | 1007 | self.client.post('/test_admin/admin/logout/') |
| 1008 | 1008 | |
| 1009 | 1009 | def testDeleteView(self): |
| 1010 | 1010 | """Delete view should restrict access and actually delete items.""" |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 1019 | 1019 | post = self.client.post('/test_admin/admin/admin_views/article/1/delete/', delete_dict) |
| 1020 | 1020 | self.assertEqual(post.status_code, 403) |
| 1021 | 1021 | self.assertEqual(Article.objects.all().count(), 3) |
| 1022 | | self.client.get('/test_admin/admin/logout/') |
| | 1022 | self.client.post('/test_admin/admin/logout/') |
| 1023 | 1023 | |
| 1024 | 1024 | # Delete user can delete |
| 1025 | 1025 | self.client.get('/test_admin/admin/') |
| … |
… |
class AdminViewPermissionsTest(TestCase):
|
| 1038 | 1038 | article_ct = ContentType.objects.get_for_model(Article) |
| 1039 | 1039 | logged = LogEntry.objects.get(content_type=article_ct, action_flag=DELETION) |
| 1040 | 1040 | self.assertEqual(logged.object_id, u'1') |
| 1041 | | self.client.get('/test_admin/admin/logout/') |
| | 1041 | self.client.post('/test_admin/admin/logout/') |
| 1042 | 1042 | |
| 1043 | 1043 | def testDisabledPermissionsWhenLoggedIn(self): |
| 1044 | 1044 | self.client.login(username='super', password='secret') |
| … |
… |
class SecureViewTests(TestCase):
|
| 1339 | 1339 | login = self.client.post('/test_admin/admin/secure-view/', self.super_login) |
| 1340 | 1340 | self.assertRedirects(login, '/test_admin/admin/secure-view/') |
| 1341 | 1341 | self.assertFalse(login.context) |
| 1342 | | self.client.get('/test_admin/admin/logout/') |
| | 1342 | self.client.post('/test_admin/admin/logout/') |
| 1343 | 1343 | # make sure the view removes test cookie |
| 1344 | 1344 | self.assertEqual(self.client.session.test_cookie_worked(), False) |
| 1345 | 1345 | |
| … |
… |
class SecureViewTests(TestCase):
|
| 1363 | 1363 | login = self.client.post('/test_admin/admin/secure-view/', self.adduser_login) |
| 1364 | 1364 | self.assertRedirects(login, '/test_admin/admin/secure-view/') |
| 1365 | 1365 | self.assertFalse(login.context) |
| 1366 | | self.client.get('/test_admin/admin/logout/') |
| | 1366 | self.client.post('/test_admin/admin/logout/') |
| 1367 | 1367 | |
| 1368 | 1368 | # Change User |
| 1369 | 1369 | request = self.client.get('/test_admin/admin/secure-view/') |
| … |
… |
class SecureViewTests(TestCase):
|
| 1371 | 1371 | login = self.client.post('/test_admin/admin/secure-view/', self.changeuser_login) |
| 1372 | 1372 | self.assertRedirects(login, '/test_admin/admin/secure-view/') |
| 1373 | 1373 | self.assertFalse(login.context) |
| 1374 | | self.client.get('/test_admin/admin/logout/') |
| | 1374 | self.client.post('/test_admin/admin/logout/') |
| 1375 | 1375 | |
| 1376 | 1376 | # Delete User |
| 1377 | 1377 | request = self.client.get('/test_admin/admin/secure-view/') |
| … |
… |
class SecureViewTests(TestCase):
|
| 1379 | 1379 | login = self.client.post('/test_admin/admin/secure-view/', self.deleteuser_login) |
| 1380 | 1380 | self.assertRedirects(login, '/test_admin/admin/secure-view/') |
| 1381 | 1381 | self.assertFalse(login.context) |
| 1382 | | self.client.get('/test_admin/admin/logout/') |
| | 1382 | self.client.post('/test_admin/admin/logout/') |
| 1383 | 1383 | |
| 1384 | 1384 | # Regular User should not be able to login. |
| 1385 | 1385 | request = self.client.get('/test_admin/admin/secure-view/') |
| … |
… |
class AdminViewListEditable(TestCase):
|
| 1502 | 1502 | # 4 action inputs (3 regular checkboxes, 1 checkbox to select all) |
| 1503 | 1503 | # main form submit button = 1 |
| 1504 | 1504 | # search field and search submit button = 2 |
| 1505 | | # CSRF field = 1 |
| | 1505 | # CSRF field = 1 + 1 (the logout form has a CSRF field and is on every page in the admin.) |
| 1506 | 1506 | # field to track 'select all' across paginated views = 1 |
| 1507 | 1507 | # 6 + 3 + 4 + 1 + 2 + 1 + 1 = 18 inputs |
| 1508 | | self.assertEqual(response.content.count("<input"), 18) |
| | 1508 | self.assertEqual(response.content.count("<input"), 19) |
| 1509 | 1509 | # 1 select per object = 3 selects |
| 1510 | 1510 | self.assertEqual(response.content.count("<select"), 4) |
| 1511 | 1511 | |
| … |
… |
class NeverCacheTests(TestCase):
|
| 2690 | 2690 | |
| 2691 | 2691 | def testLogout(self): |
| 2692 | 2692 | "Check the never-cache status of logout view" |
| 2693 | | response = self.client.get('/test_admin/admin/logout/') |
| | 2693 | response = self.client.post('/test_admin/admin/logout/') |
| 2694 | 2694 | self.assertEqual(get_max_age(response), 0) |
| 2695 | 2695 | |
| 2696 | 2696 | def testPasswordChange(self): |
| … |
… |
class ReadonlyTest(TestCase):
|
| 2748 | 2748 | self.assertEqual(response.status_code, 200) |
| 2749 | 2749 | self.assertNotContains(response, 'name="posted"') |
| 2750 | 2750 | # 3 fields + 2 submit buttons + 4 inline management form fields, + 2 |
| 2751 | | # hidden fields for inlines + 1 field for the inline + 2 empty form |
| 2752 | | self.assertEqual(response.content.count("<input"), 14) |
| | 2751 | # hidden fields for inlines + 1 field for the inline + 2 empty form + 1 |
| | 2752 | # input for csrf token on logout form in js. |
| | 2753 | self.assertEqual(response.content.count("<input"), 15) |
| 2753 | 2754 | self.assertContains(response, formats.localize(datetime.date.today())) |
| 2754 | 2755 | self.assertContains(response, |
| 2755 | 2756 | "<label>Awesomeness level:</label>") |
| … |
… |
class AdminCustomSaveRelatedTests(TestCase):
|
| 3222 | 3223 | |
| 3223 | 3224 | self.assertEqual('Josh Stone', Parent.objects.latest('id').name) |
| 3224 | 3225 | self.assertEqual([u'Catherine Stone', u'Paul Stone'], children_names) |
| | 3226 | |
| | 3227 | |
| | 3228 | class AdminViewLogoutTest(TestCase): |
| | 3229 | fixtures = ['admin-views-users.xml', ] |
| | 3230 | |
| | 3231 | def setUp(self): |
| | 3232 | self.client.login(username='super', password='secret') |
| | 3233 | |
| | 3234 | def tearDown(self): |
| | 3235 | self.client.logout() |
| | 3236 | |
| | 3237 | def test_logout_attempt_using_get(self): |
| | 3238 | response = self.client.get('/test_admin/admin/logout/') |
| | 3239 | self.assertEqual(response.status_code, 200) |
| | 3240 | # since we are issuing a GET request we should be rendering |
| | 3241 | # the confirmation template |
| | 3242 | self.assertTemplateUsed(response, 'admin/logout_confirmation.html') |
| | 3243 | |
| | 3244 | def test_logout_attempt_using_post(self): |
| | 3245 | # 15619 - you must POST to the logout view to actually logout. |
| | 3246 | response = self.client.post('/test_admin/admin/logout/') |
| | 3247 | self.assertEqual(response.status_code, 200) |
| | 3248 | # since we are issuing a POST request we should be logging out the |
| | 3249 | # user immediatly. |
| | 3250 | self.assertTemplateUsed(response, 'registration/logged_out.html') |
| | 3251 | |