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 | |