Add csrf token checks to team join/leave as well as event attending views. Fixes #96
This commit is contained in:
commit
f720f626eb
5 changed files with 36 additions and 11 deletions
|
@ -1,5 +1,8 @@
|
|||
import re
|
||||
import unicodedata
|
||||
from django.middleware.csrf import _sanitize_token, _compare_salted_tokens
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import PermissionDenied
|
||||
|
||||
SLUG_OK = '-_~'
|
||||
|
||||
|
@ -19,3 +22,18 @@ def slugify(s, ok=SLUG_OK, lower=True, spaces=False):
|
|||
new = re.sub('[-\s]+', '-', new)
|
||||
return new.lower() if lower else new
|
||||
|
||||
|
||||
def verify_csrf(token_key='csrftoken'):
|
||||
|
||||
def wrap_view(view_func):
|
||||
def check_csrf_token(request, *args, **kwargs):
|
||||
csrf_token = _sanitize_token(request.GET.get(token_key, ''))
|
||||
match = _compare_salted_tokens(csrf_token, request.COOKIES[settings.CSRF_COOKIE_NAME])
|
||||
if not match:
|
||||
raise PermissionDenied
|
||||
else:
|
||||
return view_func(request, *args, **kwargs)
|
||||
|
||||
return check_csrf_token
|
||||
return wrap_view
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ from .models.events import Event, EventComment, Place, PlaceSerializer, Attendee
|
|||
from .models.locale import Country ,CountrySerializer, SPR, SPRSerializer, City, CitySerializer
|
||||
from .models.profiles import Team, UserProfile, Member, Sponsor, SponsorSerializer
|
||||
from .forms import EventCommentForm
|
||||
from .utils import verify_csrf
|
||||
|
||||
import simplejson
|
||||
|
||||
|
@ -104,7 +105,9 @@ def sponsor_list(request):
|
|||
return Response(serializer.data)
|
||||
|
||||
|
||||
@verify_csrf(token_key='csrftoken')
|
||||
def join_team(request, team_id):
|
||||
|
||||
if request.user.is_anonymous:
|
||||
messages.add_message(request, messages.WARNING, message=_('You must be logged in to join a team.'))
|
||||
return redirect('show-team', team_id=team_id)
|
||||
|
@ -116,6 +119,8 @@ def join_team(request, team_id):
|
|||
messages.add_message(request, messages.SUCCESS, message=_('Welcome to the team!'))
|
||||
return redirect('show-team', team_id=team_id)
|
||||
|
||||
|
||||
@verify_csrf(token_key='csrftoken')
|
||||
def leave_team(request, team_id):
|
||||
if request.user.is_anonymous:
|
||||
messages.add_message(request, messages.WARNING, message=_('You must be logged in to leave a team.'))
|
||||
|
|
|
@ -124,13 +124,13 @@
|
|||
{% endif %}
|
||||
{% if not is_attending %}
|
||||
<div class="btn-group">
|
||||
<a href="{% url 'attend-event' event.id %}" class="btn btn-success btn-sm"><i class="fa fa-check-square-o"></i> Attend</a>
|
||||
<a href="{% url 'attend-event' event.id %}?csrftoken={{csrf_token}}" class="btn btn-success btn-sm"><i class="fa fa-check-square-o"></i> Attend</a>
|
||||
<button type="button" class="btn btn-success btn-sm dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="sr-only">Attendance options</span>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=maybe">Maybe</a>
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=no">No</a>
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=maybe&csrftoken={{csrf_token}}">Maybe</a>
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=no&csrftoken={{csrf_token}}">No</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -287,20 +287,20 @@
|
|||
{% if attendee.status == attendee.YES %}
|
||||
<span class="badge badge-success dropdown-toggle align-top" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ attendee.status_name }}</span>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=maybe">Maybe</a>
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=no">No</a>
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=maybe&csrftoken={{csrf_token}}">Maybe</a>
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=no&csrftoken={{csrf_token}}">No</a>
|
||||
</div>
|
||||
{% elif attendee.status == attendee.MAYBE %}
|
||||
<span class="badge badge-default dropdown-toggle align-top" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ attendee.status_name }}</span>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=yes">Yes</a>
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=no">No</a>
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=yes&csrftoken={{csrf_token}}">Yes</a>
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=no&csrftoken={{csrf_token}}">No</a>
|
||||
</div>
|
||||
{% elif attendee.status == attendee.NO %}
|
||||
<span class="badge badge-danger dropdown-toggle align-top" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ attendee.status_name }}</span>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=yes">Yes</a>
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=maybe">Maybe</a>
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=yes&csrftoken={{csrf_token}}">Yes</a>
|
||||
<a class="dropdown-item" href="{% url 'attend-event' event.id %}?response=maybe&csrftoken={{csrf_token}}">Maybe</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
|
|
|
@ -35,9 +35,9 @@
|
|||
<a href="{% url 'manage-members' team.id %}" class="btn btn-secondary btn-sm"><i class="fa fa-users"></i> Manage Members</a>
|
||||
{% endif %}
|
||||
{% if is_member %}
|
||||
{% if not team.owner_profile == request.user.profile %}<a href="{% url 'leave-team' team.id %}" class="btn btn-danger btn-sm">Leave Team</a>{% endif %}
|
||||
{% if not team.owner_profile == request.user.profile %}<a href="{% url 'leave-team' team.id %}?csrftoken={{csrf_token}}" class="btn btn-danger btn-sm">Leave Team</a>{% endif %}
|
||||
{% else %}
|
||||
<a href="{% url 'join-team' team.id %}" class="btn btn-success btn-sm">Join Team</a>
|
||||
<a href="{% url 'join-team' team.id %}?csrftoken={{csrf_token}}" class="btn btn-success btn-sm">Join Team</a>
|
||||
{% endif %}
|
||||
<hr/>
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ from events.forms import (
|
|||
SponsorForm,
|
||||
)
|
||||
from events import location
|
||||
from events.utils import verify_csrf
|
||||
|
||||
from accounts.models import EmailRecord
|
||||
|
||||
|
@ -421,6 +422,7 @@ def contact_attendee(attendee, body, sender):
|
|||
)
|
||||
|
||||
|
||||
@verify_csrf(token_key='csrftoken')
|
||||
def attend_event(request, event_id):
|
||||
event = get_object_or_404(Event, id=event_id)
|
||||
if request.user.is_anonymous:
|
||||
|
|
Loading…
Reference in a new issue