Fix community list track/untrack to use POST rather than GET

- Legacy-Id: 10660
This commit is contained in:
Ole Laursen 2016-01-13 10:15:38 +00:00
parent bce152b2b9
commit e807115e81
8 changed files with 133 additions and 80 deletions

30
ietf/community/tests.py Normal file
View file

@ -0,0 +1,30 @@
import json
from django.core.urlresolvers import reverse as urlreverse
from ietf.community.models import CommunityList
from ietf.utils.test_data import make_test_data
from ietf.utils.test_utils import login_testing_unauthorized, TestCase
class CommunityListTests(TestCase):
def test_track_untrack_document(self):
draft = make_test_data()
url = urlreverse("community_track_document", kwargs={ "name": draft.name })
login_testing_unauthorized(self, "plain", url)
# track
r = self.client.post(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(r.status_code, 200)
self.assertEqual(json.loads(r.content)["success"], True)
clist = CommunityList.objects.get(user__username="plain")
self.assertEqual(list(clist.added_ids.all()), [draft])
# untrack
url = urlreverse("community_untrack_document", kwargs={ "name": draft.name })
r = self.client.post(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(r.status_code, 200)
self.assertEqual(json.loads(r.content)["success"], True)
clist = CommunityList.objects.get(user__username="plain")
self.assertEqual(list(clist.added_ids.all()), [])

View file

@ -23,9 +23,10 @@ urlpatterns = patterns('ietf.community.views',
url(r'^group/(?P<acronym>[\w.@+-]+)/unsubscribe/$', 'unsubscribe_group_list', {'significant': False}, name='unsubscribe_group_list'), url(r'^group/(?P<acronym>[\w.@+-]+)/unsubscribe/$', 'unsubscribe_group_list', {'significant': False}, name='unsubscribe_group_list'),
url(r'^group/(?P<acronym>[\w.@+-]+)/unsubscribe/significant/$', 'unsubscribe_group_list', {'significant': True}, name='unsubscribe_significant_group_list'), url(r'^group/(?P<acronym>[\w.@+-]+)/unsubscribe/significant/$', 'unsubscribe_group_list', {'significant': True}, name='unsubscribe_significant_group_list'),
url(r'^add_track_document/(?P<document_name>[^/]+)/$', 'add_track_document', name='community_add_track_document'), url(r'^trackdocument/(?P<name>[^/]+)/$', 'track_document', name='community_track_document'),
url(r'^remove_track_document/(?P<document_name>[^/]+)/$', 'remove_track_document', name='community_remove_track_document'), url(r'^untrackdocument/(?P<name>[^/]+)/$', 'untrack_document', name='community_untrack_document'),
url(r'^(?P<list_id>[\d]+)/remove_document/(?P<document_name>[^/]+)/$', 'remove_document', name='community_remove_document'),
url(r'^(?P<list_id>[\d]+)/remove_document/(?P<name>[^/]+)/$', 'remove_document', name='community_remove_document'),
url(r'^(?P<list_id>[\d]+)/remove_rule/(?P<rule_id>[^/]+)/$', 'remove_rule', name='community_remove_rule'), url(r'^(?P<list_id>[\d]+)/remove_rule/(?P<rule_id>[^/]+)/$', 'remove_rule', name='community_remove_rule'),
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'), 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'),
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'), 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'),

View file

@ -7,15 +7,15 @@ import json
from django.db import IntegrityError from django.db import IntegrityError
from django.conf import settings from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME from django.contrib.auth import REDIRECT_FIELD_NAME
from django.http import HttpResponse, Http404, HttpResponseRedirect from django.http import HttpResponse, HttpResponseForbidden, Http404, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render_to_response from django.shortcuts import get_object_or_404, render, redirect
from django.template import RequestContext
from django.utils.http import urlquote from django.utils.http import urlquote
from django.contrib.auth.decorators import login_required
from ietf.community.models import CommunityList, Rule, EmailSubscription from ietf.community.models import CommunityList, Rule, EmailSubscription
from ietf.community.forms import RuleForm, DisplayForm, SubscribeForm, UnSubscribeForm from ietf.community.forms import RuleForm, DisplayForm, SubscribeForm, UnSubscribeForm
from ietf.group.models import Group from ietf.group.models import Group
from ietf.doc.models import DocEvent, DocAlias from ietf.doc.models import DocEvent, Document
def _manage_list(request, clist): def _manage_list(request, clist):
@ -41,12 +41,11 @@ def _manage_list(request, clist):
rule_form = RuleForm(clist=clist) rule_form = RuleForm(clist=clist)
display_form = DisplayForm(instance=display_config) display_form = DisplayForm(instance=display_config)
clist = CommunityList.objects.get(id=clist.id) clist = CommunityList.objects.get(id=clist.id)
return render_to_response('community/manage_clist.html', return render(request, 'community/manage_clist.html',
{'cl': clist, {'cl': clist,
'dc': display_config, 'dc': display_config,
'display_form': display_form, 'display_form': display_form,
'rule_form': rule_form}, 'rule_form': rule_form})
context_instance=RequestContext(request))
def manage_personal_list(request): def manage_personal_list(request):
@ -74,52 +73,49 @@ def manage_group_list(request, acronym):
return HttpResponseRedirect('%s?%s=%s' % tup) return HttpResponseRedirect('%s?%s=%s' % tup)
return _manage_list(request, clist) return _manage_list(request, clist)
@login_required
def track_document(request, name):
doc = get_object_or_404(Document, docalias__name=name)
def add_track_document(request, document_name): if request.method == "POST":
"""supports the "Track this document" functionality clist = CommunityList.objects.get_or_create(user=request.user)[0]
clist.added_ids.add(doc)
This is exposed in the document view and in document search results.""" if request.is_ajax():
if not request.user.is_authenticated(): return HttpResponse(json.dumps({ 'success': True }), content_type='text/plain')
path = urlquote(request.get_full_path()) else:
tup = settings.LOGIN_URL, REDIRECT_FIELD_NAME, path return redirect("manage_personal_list")
return HttpResponseRedirect('%s?%s=%s' % tup)
doc = get_object_or_404(DocAlias, name=document_name).document
clist = CommunityList.objects.get_or_create(user=request.user)[0]
clist.update()
return add_document_to_list(request, clist, doc)
def remove_track_document(request, document_name): return render(request, "community/track_document.html", {
"""supports the "Untrack this document" functionality "name": doc.name,
})
This is exposed in the document view and in document search results."""
clist = CommunityList.objects.get_or_create(user=request.user)[0]
if not clist.check_manager(request.user):
path = urlquote(request.get_full_path())
tup = settings.LOGIN_URL, REDIRECT_FIELD_NAME, path
return HttpResponseRedirect('%s?%s=%s' % tup)
doc = get_object_or_404(DocAlias, name=document_name).document
clist.added_ids.remove(doc)
clist.update()
return HttpResponse(json.dumps({'success': True}), content_type='text/plain')
def remove_document(request, list_id, document_name): @login_required
def untrack_document(request, name):
doc = get_object_or_404(Document, docalias__name=name)
clist = get_object_or_404(CommunityList, user=request.user)
if request.method == "POST":
clist = CommunityList.objects.get_or_create(user=request.user)[0]
clist.added_ids.remove(doc)
if request.is_ajax():
return HttpResponse(json.dumps({ 'success': True }), content_type='text/plain')
else:
return redirect("manage_personal_list")
return render(request, "community/untrack_document.html", {
"name": doc.name,
})
@login_required
def remove_document(request, list_id, name):
clist = get_object_or_404(CommunityList, pk=list_id) clist = get_object_or_404(CommunityList, pk=list_id)
if not clist.check_manager(request.user): if not clist.check_manager(request.user):
path = urlquote(request.get_full_path()) return HttpResponseForbidden("You do not have permission to access this view")
tup = settings.LOGIN_URL, REDIRECT_FIELD_NAME, path
return HttpResponseRedirect('%s?%s=%s' % tup)
doc = get_object_or_404(DocAlias, name=document_name).document
clist.added_ids.remove(doc)
clist.update()
return HttpResponseRedirect(clist.get_manage_url())
def add_document_to_list(request, clist, doc): doc = get_object_or_404(Document, docalias__name=name)
if not clist.check_manager(request.user): clist.added_ids.remove(doc)
path = urlquote(request.get_full_path())
tup = settings.LOGIN_URL, REDIRECT_FIELD_NAME, path return HttpResponseRedirect(clist.get_manage_url())
return HttpResponseRedirect('%s?%s=%s' % tup)
clist.added_ids.add(doc)
return HttpResponse(json.dumps({'success': True}), content_type='text/plain')
def remove_rule(request, list_id, rule_id): def remove_rule(request, list_id, rule_id):
@ -135,11 +131,10 @@ def remove_rule(request, list_id, rule_id):
def _view_list(request, clist): def _view_list(request, clist):
display_config = clist.get_display_config() display_config = clist.get_display_config()
return render_to_response('community/public/view_list.html', return render(request, 'community/public/view_list.html',
{'cl': clist, {'cl': clist,
'dc': display_config, 'dc': display_config,
}, })
context_instance=RequestContext(request))
def view_personal_list(request, secret): def view_personal_list(request, secret):
@ -172,7 +167,7 @@ def _atom_view(request, clist, significant=False):
else: else:
subtitle = 'Document changes' subtitle = 'Document changes'
return render_to_response('community/public/atom.xml', return render(request, 'community/public/atom.xml',
{'cl': clist, {'cl': clist,
'entries': notifications, 'entries': notifications,
'title': title, 'title': title,
@ -180,8 +175,7 @@ def _atom_view(request, clist, significant=False):
'id': feed_id.get_urn(), 'id': feed_id.get_urn(),
'updated': datetime.datetime.today(), 'updated': datetime.datetime.today(),
}, },
content_type='text/xml', content_type='text/xml')
context_instance=RequestContext(request))
def changes_personal_list(request, secret): def changes_personal_list(request, secret):
@ -264,12 +258,11 @@ def _subscribe_list(request, clist, significant):
success = True success = True
else: else:
form = SubscribeForm(clist=clist, significant=significant) form = SubscribeForm(clist=clist, significant=significant)
return render_to_response('community/public/subscribe.html', return render(request, 'community/public/subscribe.html',
{'cl': clist, {'cl': clist,
'form': form, 'form': form,
'success': success, 'success': success,
}, })
context_instance=RequestContext(request))
def _unsubscribe_list(request, clist, significant): def _unsubscribe_list(request, clist, significant):
@ -281,13 +274,12 @@ def _unsubscribe_list(request, clist, significant):
success = True success = True
else: else:
form = UnSubscribeForm(clist=clist, significant=significant) form = UnSubscribeForm(clist=clist, significant=significant)
return render_to_response('community/public/unsubscribe.html', return render(request, 'community/public/unsubscribe.html',
{'cl': clist, {'cl': clist,
'form': form, 'form': form,
'success': success, 'success': success,
'significant': significant, 'significant': significant,
}, })
context_instance=RequestContext(request))
def subscribe_personal_list(request, secret, significant=False): def subscribe_personal_list(request, secret, significant=False):
@ -321,11 +313,10 @@ def confirm_subscription(request, list_id, email, date, confirm_hash, significan
community_list=clist, community_list=clist,
email=email, email=email,
significant=significant) significant=significant)
return render_to_response('community/public/subscription_confirm.html', return render(request, 'community/public/subscription_confirm.html',
{'cl': clist, {'cl': clist,
'significant': significant, 'significant': significant,
}, })
context_instance=RequestContext(request))
def confirm_significant_subscription(request, list_id, email, date, confirm_hash): 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
community_list=clist, community_list=clist,
email=email, email=email,
significant=significant).delete() significant=significant).delete()
return render_to_response('community/public/unsubscription_confirm.html', return render(request, 'community/public/unsubscription_confirm.html',
{'cl': clist, {'cl': clist,
'significant': significant, 'significant': significant,
}, })
context_instance=RequestContext(request))
def confirm_significant_unsubscription(request, list_id, email, date, confirm_hash): def confirm_significant_unsubscription(request, list_id, email, date, confirm_hash):

View file

@ -105,19 +105,19 @@ $(document).ready(function () {
var trigger = $(this); var trigger = $(this);
$.ajax({ $.ajax({
url: trigger.attr('href'), url: trigger.attr('href'),
type: 'GET', type: 'POST',
cache: false, cache: false,
dataType: 'json', dataType: 'json',
success: function(response){ success: function(response){
if (response.success) { if (response.success) {
trigger.parent().find(".tooltip").remove(); trigger.parent().find(".tooltip").remove();
trigger.find("span.fa").toggleClass("fa-bookmark fa-bookmark-o"); trigger.find("span.fa").toggleClass("fa-bookmark fa-bookmark-o");
if (trigger.hasClass('btn')) { if (trigger.hasClass('btn')) {
trigger.attr('disabled', true).blur(); trigger.attr('disabled', true).blur();
} else { } else {
trigger.contents().unwrap().blur(); trigger.contents().unwrap().blur();
}
} }
}
} }
}); });
}); });

View file

@ -0,0 +1,16 @@
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}{% origin %}
{% load bootstrap3 %}
{% block title %}Track document {{ name }}{% endblock %}
{% bootstrap_messages %}
<form method="post">
{% csrf_token %}
<p>Add {{ name }} to the list?</p>
{% buttons %}
<input type="submit" class="btn btn-primary" value="Track document">
{% endbuttons %}
</form>

View file

@ -0,0 +1,16 @@
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}{% origin %}
{% load bootstrap3 %}
{% block title %}Remove tracking of document {{ name }}{% endblock %}
{% bootstrap_messages %}
<form method="post">
{% csrf_token %}
<p>Remove {{ name }} from the list?</p>
{% buttons %}
<input type="submit" class="btn btn-primary" value="Remove tracking of document">
{% endbuttons %}
</form>

View file

@ -435,9 +435,9 @@
</div> </div>
{% if user.is_authenticated %} {% if user.is_authenticated %}
{% if tracking_document %} {% if tracking_document %}
<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> <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>
{% else %} {% else %}
<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> <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>
{% endif %} {% endif %}
{% endif %} {% endif %}

View file

@ -14,11 +14,11 @@
<td> <td>
{% if user.is_authenticated %} {% if user.is_authenticated %}
{% if doc.name in doc_is_tracked %} {% if doc.name in doc_is_tracked %}
<a href="{% url "community_remove_track_document" doc.name %}" class="community-list-add-remove-doc" title="Remove from your personal ID list"> <a href="{% url "community_untrack_document" doc.name %}" class="community-list-add-remove-doc" title="Remove from your personal ID list">
<span class="fa fa-bookmark"></span> <span class="fa fa-bookmark"></span>
</a> </a>
{% else %} {% else %}
<a href="{% url "community_add_track_document" doc.name %}" class="community-list-add-remove-doc" title="Add to your personal ID list"> <a href="{% url "community_track_document" doc.name %}" class="community-list-add-remove-doc" title="Add to your personal ID list">
<span class="fa fa-bookmark-o"></span> <span class="fa fa-bookmark-o"></span>
</a> </a>
{% endif %} {% endif %}