Skip to content

Commit

Permalink
votes: increase token length to 16
Browse files Browse the repository at this point in the history
  • Loading branch information
goapunk committed Feb 20, 2023
1 parent 39e4f3a commit 930b1e1
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 14 deletions.
11 changes: 5 additions & 6 deletions meinberlin/apps/votes/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ def __init__(self, placeholder=None, *args, **kwargs):
widget = TextInput(
attrs={
"class": "form-control",
"minlength": 12,
"maxlength": 14,
"minlength": 16,
"maxlength": 19,
"placeholder": placeholder,
}
)
Expand All @@ -23,21 +23,20 @@ def __init__(self, placeholder=None, *args, **kwargs):
}

def clean(self, value):

# ensure no spaces or dashes
value = value.replace(" ", "").replace("-", "")

# check the value is not too short or too long
if len(value) < 12:
if len(value) < 16:
raise forms.ValidationError(self.error_messages["invalid_short"])
elif len(value) > 12:
elif len(value) > 16:
raise forms.ValidationError(self.error_messages["invalid_long"])

return value


class TokenForm(forms.Form):
token = VotingTokenField(placeholder="0000-0000-0000")
token = VotingTokenField(placeholder="0000-0000-0000-0000")

def __init__(self, *args, **kwargs):
self.module_id = kwargs.pop("module_id")
Expand Down
113 changes: 113 additions & 0 deletions meinberlin/apps/votes/migrations/0005_alter_votingtoken_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Generated by Django 3.2.17 on 2023-02-16 13:45

from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import meinberlin.apps.votes.models


class Migration(migrations.Migration):
dependencies = [
("a4modules", "0006_module_blueprint_type"),
("contenttypes", "0002_remove_content_type_name"),
("meinberlin_votes", "0004_verbose_name_created_modified"),
]

operations = [
migrations.DeleteModel(
name="VotingToken",
),
migrations.DeleteModel(
name="TokenVote",
),
migrations.CreateModel(
name="VotingToken",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"token",
models.CharField(
blank=True,
default=meinberlin.apps.votes.models.get_token_16,
editable=False,
max_length=40,
),
),
(
"token_hash",
models.CharField(editable=False, max_length=128, unique=True),
),
("allowed_votes", models.PositiveSmallIntegerField(default=5)),
("package_number", models.PositiveIntegerField()),
(
"is_active",
models.BooleanField(
default=True,
help_text="Designates whether this token should be treated as active. Unselect this instead of deleting tokens.",
),
),
(
"module",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="a4modules.module",
),
),
],
),
migrations.CreateModel(
name="TokenVote",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"created",
models.DateTimeField(
default=django.utils.timezone.now,
editable=False,
verbose_name="Created",
),
),
(
"modified",
models.DateTimeField(
blank=True, editable=False, null=True, verbose_name="Modified"
),
),
("object_pk", models.PositiveIntegerField()),
(
"content_type",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="contenttypes.contenttype",
),
),
(
"token",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="meinberlin_votes.votingtoken",
),
),
],
options={
"unique_together": {("content_type", "object_pk", "token")},
"index_together": {("content_type", "object_pk")},
},
),
]
9 changes: 6 additions & 3 deletions meinberlin/apps/votes/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def get_token(length):
return "".join(secrets.choice(alphabet) for i in range(length))


# only used by migration
def get_token_12():
return get_token(12)

Expand Down Expand Up @@ -57,7 +58,7 @@ def get_or_create_salt_for_module(module):

class VotingToken(models.Model):
token = models.CharField(
max_length=40, default=get_token_12, blank=True, editable=False
max_length=40, default=get_token_16, blank=True, editable=False
)
token_hash = models.CharField(max_length=128, editable=False, unique=True)
module = models.ForeignKey(Module, on_delete=models.CASCADE)
Expand All @@ -82,7 +83,7 @@ def save(self, *args, **kwargs):
if i == 3:
raise
else:
self.token = get_token_12()
self.token = get_token_16()
self.token_hash = self.hash_token(self.token, self.module)
else:
raise
Expand Down Expand Up @@ -146,7 +147,9 @@ def get_voting_token_by_hash(token_hash, module):
return None

def __str__(self):
return "{}-{}-{}".format(self.token[0:4], self.token[4:8], self.token[8:12])
return "{}-{}-{}-{}".format(
self.token[0:4], self.token[4:8], self.token[8:12], self.token[12:16]
)


class TokenVote(base.TimeStampedModel):
Expand Down
4 changes: 2 additions & 2 deletions meinberlin/apps/votes/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from adhocracy4.modules.models import Module
from meinberlin.apps.votes.models import VotingToken
from meinberlin.apps.votes.models import get_token_12
from meinberlin.apps.votes.models import get_token_16

# Number of tokens to insert into database per bulk_create
BATCH_SIZE = int(1e3)
Expand Down Expand Up @@ -72,7 +72,7 @@ def generate_voting_tokens_batch(


def get_token_and_hash(module, package_number):
token = get_token_12()
token = get_token_16()
token_hash = VotingToken.hash_token(token, module)
return VotingToken(
token=token, token_hash=token_hash, module=module, package_number=package_number
Expand Down
2 changes: 1 addition & 1 deletion meinberlin/test/factories/votes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class VotingTokenFactory(factory.django.DjangoModelFactory):
class Meta:
model = voting_models.VotingToken

token = fuzzy.FuzzyText(length=12, chars=string.ascii_letters + string.digits)
token = fuzzy.FuzzyText(length=16, chars=string.ascii_letters + string.digits)
module = factory.SubFactory(a4_factories.ModuleFactory)
allowed_votes = 5
package_number = 0
Expand Down
7 changes: 5 additions & 2 deletions tests/votes/test_votes_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
@pytest.mark.django_db
def test_voting_token_str(voting_token):
voting_token_string = voting_token.__str__()
assert voting_token_string == "{}-{}-{}".format(
voting_token.token[0:4], voting_token.token[4:8], voting_token.token[8:12]
assert voting_token_string == "{}-{}-{}-{}".format(
voting_token.token[0:4],
voting_token.token[4:8],
voting_token.token[8:12],
voting_token.token[12:16],
)


Expand Down

0 comments on commit 930b1e1

Please sign in to comment.