Skip to content

Commit e807115

Browse files
committed
Fix community list track/untrack to use POST rather than GET
- Legacy-Id: 10660
1 parent bce152b commit e807115

8 files changed

Lines changed: 135 additions & 82 deletions

File tree

ietf/community/tests.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import json
2+
3+
from django.core.urlresolvers import reverse as urlreverse
4+
5+
from ietf.community.models import CommunityList
6+
from ietf.utils.test_data import make_test_data
7+
from ietf.utils.test_utils import login_testing_unauthorized, TestCase
8+
9+
class CommunityListTests(TestCase):
10+
def test_track_untrack_document(self):
11+
draft = make_test_data()
12+
13+
url = urlreverse("community_track_document", kwargs={ "name": draft.name })
14+
login_testing_unauthorized(self, "plain", url)
15+
16+
# track
17+
r = self.client.post(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
18+
self.assertEqual(r.status_code, 200)
19+
self.assertEqual(json.loads(r.content)["success"], True)
20+
clist = CommunityList.objects.get(user__username="plain")
21+
self.assertEqual(list(clist.added_ids.all()), [draft])
22+
23+
# untrack
24+
url = urlreverse("community_untrack_document", kwargs={ "name": draft.name })
25+
r = self.client.post(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
26+
self.assertEqual(r.status_code, 200)
27+
self.assertEqual(json.loads(r.content)["success"], True)
28+
clist = CommunityList.objects.get(user__username="plain")
29+
self.assertEqual(list(clist.added_ids.all()), [])
30+

ietf/community/urls.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@
2323
url(r'^group/(?P<acronym>[\w.@+-]+)/unsubscribe/$', 'unsubscribe_group_list', {'significant': False}, name='unsubscribe_group_list'),
2424
url(r'^group/(?P<acronym>[\w.@+-]+)/unsubscribe/significant/$', 'unsubscribe_group_list', {'significant': True}, name='unsubscribe_significant_group_list'),
2525

26-
url(r'^add_track_document/(?P<document_name>[^/]+)/$', 'add_track_document', name='community_add_track_document'),
27-
url(r'^remove_track_document/(?P<document_name>[^/]+)/$', 'remove_track_document', name='community_remove_track_document'),
28-
url(r'^(?P<list_id>[\d]+)/remove_document/(?P<document_name>[^/]+)/$', 'remove_document', name='community_remove_document'),
26+
url(r'^trackdocument/(?P<name>[^/]+)/$', 'track_document', name='community_track_document'),
27+
url(r'^untrackdocument/(?P<name>[^/]+)/$', 'untrack_document', name='community_untrack_document'),
28+
29+
url(r'^(?P<list_id>[\d]+)/remove_document/(?P<name>[^/]+)/$', 'remove_document', name='community_remove_document'),
2930
url(r'^(?P<list_id>[\d]+)/remove_rule/(?P<rule_id>[^/]+)/$', 'remove_rule', name='community_remove_rule'),
3031
url(r'^(?P<list_id>[\d]+)/subscribe/confirm/(?P<email>[\w.@+-]+)/(?P<date>[\d]+)/(?P<confirm_hash>[a-f0-9]+)/$', 'confirm_subscription', name='confirm_subscription'),
3132
url(r'^(?P<list_id>[\d]+)/subscribe/significant/confirm/(?P<email>[\w.@+-]+)/(?P<date>[\d]+)/(?P<confirm_hash>[a-f0-9]+)/$', 'confirm_significant_subscription', name='confirm_significant_subscription'),

ietf/community/views.py

Lines changed: 57 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
from django.db import IntegrityError
88
from django.conf import settings
99
from django.contrib.auth import REDIRECT_FIELD_NAME
10-
from django.http import HttpResponse, Http404, HttpResponseRedirect
11-
from django.shortcuts import get_object_or_404, render_to_response
12-
from django.template import RequestContext
10+
from django.http import HttpResponse, HttpResponseForbidden, Http404, HttpResponseRedirect
11+
from django.shortcuts import get_object_or_404, render, redirect
1312
from django.utils.http import urlquote
13+
from django.contrib.auth.decorators import login_required
1414

1515
from ietf.community.models import CommunityList, Rule, EmailSubscription
1616
from ietf.community.forms import RuleForm, DisplayForm, SubscribeForm, UnSubscribeForm
1717
from ietf.group.models import Group
18-
from ietf.doc.models import DocEvent, DocAlias
18+
from ietf.doc.models import DocEvent, Document
1919

2020

2121
def _manage_list(request, clist):
@@ -41,12 +41,11 @@ def _manage_list(request, clist):
4141
rule_form = RuleForm(clist=clist)
4242
display_form = DisplayForm(instance=display_config)
4343
clist = CommunityList.objects.get(id=clist.id)
44-
return render_to_response('community/manage_clist.html',
44+
return render(request, 'community/manage_clist.html',
4545
{'cl': clist,
4646
'dc': display_config,
4747
'display_form': display_form,
48-
'rule_form': rule_form},
49-
context_instance=RequestContext(request))
48+
'rule_form': rule_form})
5049

5150

5251
def manage_personal_list(request):
@@ -74,52 +73,49 @@ def manage_group_list(request, acronym):
7473
return HttpResponseRedirect('%s?%s=%s' % tup)
7574
return _manage_list(request, clist)
7675

77-
78-
def add_track_document(request, document_name):
79-
"""supports the "Track this document" functionality
80-
81-
This is exposed in the document view and in document search results."""
82-
if not request.user.is_authenticated():
83-
path = urlquote(request.get_full_path())
84-
tup = settings.LOGIN_URL, REDIRECT_FIELD_NAME, path
85-
return HttpResponseRedirect('%s?%s=%s' % tup)
86-
doc = get_object_or_404(DocAlias, name=document_name).document
87-
clist = CommunityList.objects.get_or_create(user=request.user)[0]
88-
clist.update()
89-
return add_document_to_list(request, clist, doc)
90-
91-
def remove_track_document(request, document_name):
92-
"""supports the "Untrack this document" functionality
93-
94-
This is exposed in the document view and in document search results."""
95-
clist = CommunityList.objects.get_or_create(user=request.user)[0]
96-
if not clist.check_manager(request.user):
97-
path = urlquote(request.get_full_path())
98-
tup = settings.LOGIN_URL, REDIRECT_FIELD_NAME, path
99-
return HttpResponseRedirect('%s?%s=%s' % tup)
100-
doc = get_object_or_404(DocAlias, name=document_name).document
101-
clist.added_ids.remove(doc)
102-
clist.update()
103-
return HttpResponse(json.dumps({'success': True}), content_type='text/plain')
104-
105-
def remove_document(request, list_id, document_name):
76+
@login_required
77+
def track_document(request, name):
78+
doc = get_object_or_404(Document, docalias__name=name)
79+
80+
if request.method == "POST":
81+
clist = CommunityList.objects.get_or_create(user=request.user)[0]
82+
clist.added_ids.add(doc)
83+
if request.is_ajax():
84+
return HttpResponse(json.dumps({ 'success': True }), content_type='text/plain')
85+
else:
86+
return redirect("manage_personal_list")
87+
88+
return render(request, "community/track_document.html", {
89+
"name": doc.name,
90+
})
91+
92+
@login_required
93+
def untrack_document(request, name):
94+
doc = get_object_or_404(Document, docalias__name=name)
95+
clist = get_object_or_404(CommunityList, user=request.user)
96+
97+
if request.method == "POST":
98+
clist = CommunityList.objects.get_or_create(user=request.user)[0]
99+
clist.added_ids.remove(doc)
100+
if request.is_ajax():
101+
return HttpResponse(json.dumps({ 'success': True }), content_type='text/plain')
102+
else:
103+
return redirect("manage_personal_list")
104+
105+
return render(request, "community/untrack_document.html", {
106+
"name": doc.name,
107+
})
108+
109+
@login_required
110+
def remove_document(request, list_id, name):
106111
clist = get_object_or_404(CommunityList, pk=list_id)
107112
if not clist.check_manager(request.user):
108-
path = urlquote(request.get_full_path())
109-
tup = settings.LOGIN_URL, REDIRECT_FIELD_NAME, path
110-
return HttpResponseRedirect('%s?%s=%s' % tup)
111-
doc = get_object_or_404(DocAlias, name=document_name).document
113+
return HttpResponseForbidden("You do not have permission to access this view")
114+
115+
doc = get_object_or_404(Document, docalias__name=name)
112116
clist.added_ids.remove(doc)
113-
clist.update()
114-
return HttpResponseRedirect(clist.get_manage_url())
115117

116-
def add_document_to_list(request, clist, doc):
117-
if not clist.check_manager(request.user):
118-
path = urlquote(request.get_full_path())
119-
tup = settings.LOGIN_URL, REDIRECT_FIELD_NAME, path
120-
return HttpResponseRedirect('%s?%s=%s' % tup)
121-
clist.added_ids.add(doc)
122-
return HttpResponse(json.dumps({'success': True}), content_type='text/plain')
118+
return HttpResponseRedirect(clist.get_manage_url())
123119

124120

125121
def remove_rule(request, list_id, rule_id):
@@ -135,11 +131,10 @@ def remove_rule(request, list_id, rule_id):
135131

136132
def _view_list(request, clist):
137133
display_config = clist.get_display_config()
138-
return render_to_response('community/public/view_list.html',
134+
return render(request, 'community/public/view_list.html',
139135
{'cl': clist,
140136
'dc': display_config,
141-
},
142-
context_instance=RequestContext(request))
137+
})
143138

144139

145140
def view_personal_list(request, secret):
@@ -172,16 +167,15 @@ def _atom_view(request, clist, significant=False):
172167
else:
173168
subtitle = 'Document changes'
174169

175-
return render_to_response('community/public/atom.xml',
170+
return render(request, 'community/public/atom.xml',
176171
{'cl': clist,
177172
'entries': notifications,
178173
'title': title,
179174
'subtitle': subtitle,
180175
'id': feed_id.get_urn(),
181176
'updated': datetime.datetime.today(),
182177
},
183-
content_type='text/xml',
184-
context_instance=RequestContext(request))
178+
content_type='text/xml')
185179

186180

187181
def changes_personal_list(request, secret):
@@ -264,12 +258,11 @@ def _subscribe_list(request, clist, significant):
264258
success = True
265259
else:
266260
form = SubscribeForm(clist=clist, significant=significant)
267-
return render_to_response('community/public/subscribe.html',
261+
return render(request, 'community/public/subscribe.html',
268262
{'cl': clist,
269263
'form': form,
270264
'success': success,
271-
},
272-
context_instance=RequestContext(request))
265+
})
273266

274267

275268
def _unsubscribe_list(request, clist, significant):
@@ -281,13 +274,12 @@ def _unsubscribe_list(request, clist, significant):
281274
success = True
282275
else:
283276
form = UnSubscribeForm(clist=clist, significant=significant)
284-
return render_to_response('community/public/unsubscribe.html',
277+
return render(request, 'community/public/unsubscribe.html',
285278
{'cl': clist,
286279
'form': form,
287280
'success': success,
288281
'significant': significant,
289-
},
290-
context_instance=RequestContext(request))
282+
})
291283

292284

293285
def subscribe_personal_list(request, secret, significant=False):
@@ -321,11 +313,10 @@ def confirm_subscription(request, list_id, email, date, confirm_hash, significan
321313
community_list=clist,
322314
email=email,
323315
significant=significant)
324-
return render_to_response('community/public/subscription_confirm.html',
316+
return render(request, 'community/public/subscription_confirm.html',
325317
{'cl': clist,
326318
'significant': significant,
327-
},
328-
context_instance=RequestContext(request))
319+
})
329320

330321

331322
def confirm_significant_subscription(request, list_id, email, date, confirm_hash):
@@ -341,11 +332,10 @@ def confirm_unsubscription(request, list_id, email, date, confirm_hash, signific
341332
community_list=clist,
342333
email=email,
343334
significant=significant).delete()
344-
return render_to_response('community/public/unsubscription_confirm.html',
335+
return render(request, 'community/public/unsubscription_confirm.html',
345336
{'cl': clist,
346337
'significant': significant,
347-
},
348-
context_instance=RequestContext(request))
338+
})
349339

350340

351341
def confirm_significant_unsubscription(request, list_id, email, date, confirm_hash):

ietf/static/ietf/js/ietf.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,19 +105,19 @@ $(document).ready(function () {
105105
var trigger = $(this);
106106
$.ajax({
107107
url: trigger.attr('href'),
108-
type: 'GET',
108+
type: 'POST',
109109
cache: false,
110110
dataType: 'json',
111111
success: function(response){
112112
if (response.success) {
113-
trigger.parent().find(".tooltip").remove();
114-
trigger.find("span.fa").toggleClass("fa-bookmark fa-bookmark-o");
115-
if (trigger.hasClass('btn')) {
116-
trigger.attr('disabled', true).blur();
117-
} else {
118-
trigger.contents().unwrap().blur();
113+
trigger.parent().find(".tooltip").remove();
114+
trigger.find("span.fa").toggleClass("fa-bookmark fa-bookmark-o");
115+
if (trigger.hasClass('btn')) {
116+
trigger.attr('disabled', true).blur();
117+
} else {
118+
trigger.contents().unwrap().blur();
119+
}
119120
}
120-
}
121121
}
122122
});
123123
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{# Copyright The IETF Trust 2015, All Rights Reserved #}
2+
{% load origin %}{% origin %}
3+
{% load bootstrap3 %}
4+
5+
{% block title %}Track document {{ name }}{% endblock %}
6+
7+
{% bootstrap_messages %}
8+
9+
<form method="post">
10+
{% csrf_token %}
11+
<p>Add {{ name }} to the list?</p>
12+
13+
{% buttons %}
14+
<input type="submit" class="btn btn-primary" value="Track document">
15+
{% endbuttons %}
16+
</form>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{# Copyright The IETF Trust 2015, All Rights Reserved #}
2+
{% load origin %}{% origin %}
3+
{% load bootstrap3 %}
4+
5+
{% block title %}Remove tracking of document {{ name }}{% endblock %}
6+
7+
{% bootstrap_messages %}
8+
9+
<form method="post">
10+
{% csrf_token %}
11+
<p>Remove {{ name }} from the list?</p>
12+
13+
{% buttons %}
14+
<input type="submit" class="btn btn-primary" value="Remove tracking of document">
15+
{% endbuttons %}
16+
</form>

ietf/templates/doc/document_draft.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,9 +435,9 @@
435435
</div>
436436
{% if user.is_authenticated %}
437437
{% if tracking_document %}
438-
<a class="btn btn-default btn-xs community-list-add-remove-doc" href="{% url "community_remove_track_document" doc.name %}" title="Remove from your personal ID list"><span class="fa fa-bookmark-o"></span> Untrack</a>
438+
<a class="btn btn-default btn-xs community-list-add-remove-doc" href="{% url "community_untrack_document" doc.name %}" title="Remove from your personal ID list"><span class="fa fa-bookmark-o"></span> Untrack</a>
439439
{% else %}
440-
<a class="btn btn-default btn-xs community-list-add-remove-doc" href="{% url "community_add_track_document" doc.name %}" title="Add to your personal ID list"><span class="fa fa-bookmark"></span> Track</a>
440+
<a class="btn btn-default btn-xs community-list-add-remove-doc" href="{% url "community_track_document" doc.name %}" title="Add to your personal ID list"><span class="fa fa-bookmark"></span> Track</a>
441441
{% endif %}
442442
{% endif %}
443443

ietf/templates/doc/search/search_result_row.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
<td>
1515
{% if user.is_authenticated %}
1616
{% if doc.name in doc_is_tracked %}
17-
<a href="{% url "community_remove_track_document" doc.name %}" class="community-list-add-remove-doc" title="Remove from your personal ID list">
17+
<a href="{% url "community_untrack_document" doc.name %}" class="community-list-add-remove-doc" title="Remove from your personal ID list">
1818
<span class="fa fa-bookmark"></span>
1919
</a>
2020
{% else %}
21-
<a href="{% url "community_add_track_document" doc.name %}" class="community-list-add-remove-doc" title="Add to your personal ID list">
21+
<a href="{% url "community_track_document" doc.name %}" class="community-list-add-remove-doc" title="Add to your personal ID list">
2222
<span class="fa fa-bookmark-o"></span>
2323
</a>
2424
{% endif %}

0 commit comments

Comments
 (0)