Merge lp:~rvb/maas/1.5-bug-1298790 into lp:maas/1.5

Proposed by Raphaël Badin
Status: Merged
Approved by: Raphaël Badin
Approved revision: no longer in the source branch.
Merged at revision: 2219
Proposed branch: lp:~rvb/maas/1.5-bug-1298790
Merge into: lp:maas/1.5
Diff against target: 116 lines (+70/-3)
3 files modified
src/maasserver/templates/maasserver/logout_confirm.html (+21/-0)
src/maasserver/views/account.py (+24/-2)
src/maasserver/views/tests/test_account.py (+25/-1)
To merge this branch: bzr merge lp:~rvb/maas/1.5-bug-1298790
Reviewer Review Type Date Requested Status
MAAS Maintainers Pending
Review via email: mp+213794@code.launchpad.net

Commit message

Backport revision 2219: Add a "logout confirmation" page. Using this, the logout action is protected against CSRF attacks because it uses a POST request, in conjunction with Django's CSRF protection feature.

To post a comment you must log in.
Revision history for this message
Raphaël Badin (rvb) wrote :

Simple backport: self-approving.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'src/maasserver/templates/maasserver/logout_confirm.html'
--- src/maasserver/templates/maasserver/logout_confirm.html 1970-01-01 00:00:00 +0000
+++ src/maasserver/templates/maasserver/logout_confirm.html 2014-04-02 09:48:49 +0000
@@ -0,0 +1,21 @@
1{% extends "maasserver/base.html" %}
2
3{% block nav-active-settings %}active{% endblock %}
4{% block title %}Logout{% endblock %}
5{% block page-title %}Logout{% endblock %}
6
7{% block content %}
8 <div class="block auto-width">
9 <h2>
10 Are you sure you want to log out?
11 </h2>
12 <p>
13 <form action="." method="post">{% csrf_token %}
14 <input type="hidden" name="post" value="yes" />
15 <input type="submit" value="Log out" class="right" />
16 <a href="{% url 'index' %}">Cancel</a>
17 </form>
18 </p>
19 </div>
20{% endblock %}
21
022
=== modified file 'src/maasserver/views/account.py'
--- src/maasserver/views/account.py 2013-10-07 09:12:40 +0000
+++ src/maasserver/views/account.py 2014-04-02 09:48:49 +0000
@@ -17,6 +17,7 @@
17 "logout",17 "logout",
18 ]18 ]
1919
20from django import forms
20from django.conf import settings as django_settings21from django.conf import settings as django_settings
21from django.contrib import messages22from django.contrib import messages
22from django.contrib.auth.views import (23from django.contrib.auth.views import (
@@ -25,6 +26,8 @@
25 )26 )
26from django.core.urlresolvers import reverse27from django.core.urlresolvers import reverse
27from django.http import HttpResponseRedirect28from django.http import HttpResponseRedirect
29from django.shortcuts import render_to_response
30from django.template import RequestContext
28from maasserver.models import UserProfile31from maasserver.models import UserProfile
2932
3033
@@ -39,6 +42,25 @@
39 return dj_login(request, extra_context=extra_context)42 return dj_login(request, extra_context=extra_context)
4043
4144
45class LogoutForm(forms.Form):
46 """Log-out confirmation form.
47
48 There is nothing interesting in this form, but it's needed in order
49 to get Django's CSRF protection during logout.
50 """
51
52
42def logout(request):53def logout(request):
43 messages.info(request, "You have been logged out.")54 if request.method == 'POST':
44 return dj_logout(request, next_page=reverse('login'))55 form = LogoutForm(request.POST)
56 if form.is_valid():
57 messages.info(request, "You have been logged out.")
58 return dj_logout(request, next_page=reverse('login'))
59 else:
60 form = LogoutForm()
61
62 return render_to_response(
63 'maasserver/logout_confirm.html',
64 {'form': form},
65 context_instance=RequestContext(request),
66 )
4567
=== modified file 'src/maasserver/views/tests/test_account.py'
--- src/maasserver/views/tests/test_account.py 2014-02-11 22:00:31 +0000
+++ src/maasserver/views/tests/test_account.py 2014-04-02 09:48:49 +0000
@@ -15,8 +15,13 @@
15__all__ = []15__all__ = []
1616
17from django.conf import settings17from django.conf import settings
18from django.contrib.auth import SESSION_KEY
19from django.core.urlresolvers import reverse
18from lxml.html import fromstring20from lxml.html import fromstring
19from maasserver.testing import extract_redirect21from maasserver.testing import (
22 extract_redirect,
23 get_content_links,
24 )
20from maasserver.testing.factory import factory25from maasserver.testing.factory import factory
21from maasserver.testing.testcase import MAASServerTestCase26from maasserver.testing.testcase import MAASServerTestCase
2227
@@ -44,3 +49,22 @@
44 self.client.login(username=user.username, password=password)49 self.client.login(username=user.username, password=password)
45 response = self.client.get('/accounts/login/')50 response = self.client.get('/accounts/login/')
46 self.assertEqual('/', extract_redirect(response))51 self.assertEqual('/', extract_redirect(response))
52
53
54class TestLogout(MAASServerTestCase):
55
56 def test_logout_link_present_on_homepage(self):
57 self.client_log_in()
58 response = self.client.get(reverse('index'))
59 logout_link = reverse('logout')
60 self.assertIn(
61 logout_link,
62 get_content_links(response, element='#user-options'))
63
64 def test_loggout_uses_POST(self):
65 # Using POST for logging out, along with Django's csrf_token
66 # tag, guarantees that we're protected against CSRF attacks on
67 # the loggout page.
68 self.client_log_in()
69 self.client.post(reverse('logout'))
70 self.assertNotIn(SESSION_KEY, self.client.session.keys())

Subscribers

People subscribed via source and target branches

to all changes: