Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hotfix/make token more unique #1618

Merged
merged 2 commits into from Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 7 additions & 4 deletions wcivf/apps/feedback/forms.py
@@ -1,14 +1,17 @@
import uuid

from django import forms

from .models import Feedback, FOUND_USEFUL_CHOICES, VOTE_CHOICES
from .models import (
Feedback,
FOUND_USEFUL_CHOICES,
VOTE_CHOICES,
generate_feedback_token,
)


class FeedbackForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(FeedbackForm, self).__init__(*args, **kwargs)
self.fields["token"].initial = uuid.uuid4().hex
self.fields["token"].initial = generate_feedback_token()

class Meta:
model = Feedback
Expand Down
22 changes: 22 additions & 0 deletions wcivf/apps/feedback/migrations/0007_alter_feedback_token.py
@@ -0,0 +1,22 @@
# Generated by Django 4.2.3 on 2023-07-18 16:38

from django.db import migrations, models
import feedback.models


class Migration(migrations.Migration):
dependencies = [
("feedback", "0006_feedback_flagged_as_spam"),
]

operations = [
migrations.AlterField(
model_name="feedback",
name="token",
field=models.CharField(
blank=True,
default=feedback.models.generate_feedback_token,
max_length=100,
),
),
]
10 changes: 9 additions & 1 deletion wcivf/apps/feedback/models.py
@@ -1,3 +1,5 @@
import uuid

from django.db import models

from django_extensions.db.models import TimeStampedModel
Expand All @@ -7,6 +9,10 @@
VOTE_CHOICES = (("YES", _("Yes")), ("NO", _("No")))


def generate_feedback_token():
return uuid.uuid4().hex


class Feedback(TimeStampedModel):
found_useful = models.CharField(
blank=True, max_length=100, choices=FOUND_USEFUL_CHOICES
Expand All @@ -15,5 +21,7 @@ class Feedback(TimeStampedModel):
sources = models.TextField(blank=True)
comments = models.TextField(blank=True)
source_url = models.CharField(blank=True, max_length=800)
token = models.CharField(blank=True, max_length=100)
token = models.CharField(
blank=True, max_length=100, default=generate_feedback_token
)
flagged_as_spam = models.BooleanField(default=False)
42 changes: 42 additions & 0 deletions wcivf/apps/feedback/tests/test_views.py
@@ -0,0 +1,42 @@
# Test: FeedbackFormViewTests
from django.urls import reverse
from django.test import TestCase
from feedback.views import FeedbackFormView
from feedback.models import Feedback


class FeedbackFormViewTests(TestCase, FeedbackFormView):
def setUp(self):
self.existing_feedback = Feedback()
self.existing_feedback.save()

def test_token_set_by_default(self):
request = self.client.get(reverse("feedback_form_view"))
new_token = request.context_data["object"].token
assert new_token
assert new_token != self.existing_feedback.token

def test_submit_form_saves_feedback(self):
assert Feedback.objects.count() == 1
req = self.client.post(
reverse("feedback_form_view"),
{
"found_useful": "YES",
"vote": "YES",
"source_url": "https://example.com",
"token": "123",
},
)
assert req.status_code == 302
assert Feedback.objects.count() == 2

self.client.post(
reverse("feedback_form_view"),
{
"found_useful": "YES",
"vote": "YES",
"source_url": "https://example.com",
"token": "123",
},
)
assert Feedback.objects.count() == 2
10 changes: 7 additions & 3 deletions wcivf/apps/feedback/views.py
@@ -1,3 +1,4 @@
from django.utils import timezone
from django.http import HttpResponse
from django.views.generic import View, UpdateView
from django.utils.http import url_has_allowed_host_and_scheme
Expand All @@ -24,16 +25,19 @@ def is_spam(self):
)
return akismet.check(
self.request.META["REMOTE_ADDR"],
self.request.META["HTTP_USER_AGENT"],
comment_content=self.request.POST.get("comments"),
)

def get_object(self, queryset=None):
token = self.request.POST.get("token")
try:
return Feedback.objects.get(token=token)
return Feedback.objects.get(
token=token, created__date=timezone.datetime.today()
)
except Feedback.DoesNotExist:
return Feedback(token=token)
if token:
return Feedback(token=token)
return Feedback()

def get_success_url(self):
messages.success(
Expand Down