Skip to content

Commit

Permalink
Restrict native currency logo dimensions (#374)
Browse files Browse the repository at this point in the history
currency_logo_uri size is now validated – if its image width or height is greater than 512 then a ValidationError is thrown
  • Loading branch information
fmrsabino authored Jan 4, 2022
1 parent d83b03a commit cc40485
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 2 deletions.
24 changes: 24 additions & 0 deletions src/chains/migrations/0035_alter_chain_currency_logo_uri.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 3.2.10 on 2021-12-24 12:26

from django.db import migrations, models

import chains.models


class Migration(migrations.Migration):

dependencies = [
("chains", "0034_add_public_rpc_url"),
]

operations = [
migrations.AlterField(
model_name="chain",
name="currency_logo_uri",
field=models.ImageField(
max_length=255,
upload_to=chains.models.native_currency_path,
validators=[chains.models.validate_native_currency_size],
),
),
]
12 changes: 11 additions & 1 deletion src/chains/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import os
import re
from typing import IO

from django.core.exceptions import ValidationError
from django.core.files.images import get_image_dimensions
from django.core.validators import RegexValidator
from django.db import models
from django.db.models import QuerySet
Expand All @@ -24,6 +26,12 @@ def native_currency_path(instance: "Chain", filename: str) -> str:
return f"chains/{instance.id}/currency_logo{file_extension}"


def validate_native_currency_size(image: str | IO[bytes]) -> None:
image_width, image_height = get_image_dimensions(image)
if image_width > 512 or image_height > 512:
raise ValidationError("Image width and height need to be at most 512 pixels")


class Chain(models.Model):
class RpcAuthentication(models.TextChoices):
API_KEY_PATH = "API_KEY_PATH"
Expand Down Expand Up @@ -62,7 +70,9 @@ class RpcAuthentication(models.TextChoices):
currency_symbol = models.CharField(max_length=255)
currency_decimals = models.IntegerField(default=18)
currency_logo_uri = models.ImageField(
upload_to=native_currency_path, max_length=255
validators=[validate_native_currency_size],
upload_to=native_currency_path,
max_length=255,
)
transaction_service_uri = models.URLField()
vpc_transaction_service_uri = models.URLField()
Expand Down
2 changes: 1 addition & 1 deletion src/chains/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Meta:
currency_name = factory.Faker("cryptocurrency_name")
currency_symbol = factory.Faker("cryptocurrency_code")
currency_decimals = factory.Faker("pyint")
currency_logo_uri = factory.django.ImageField()
currency_logo_uri = factory.django.ImageField(width=50, height=50)
transaction_service_uri = factory.Faker("url")
vpc_transaction_service_uri = factory.Faker("url")
theme_text_color = factory.Faker("hex_color")
Expand Down
25 changes: 25 additions & 0 deletions src/chains/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from decimal import Decimal
from typing import Any

import factory
from django.core.exceptions import ValidationError
from django.urls import reverse
from faker import Faker
from rest_framework.test import APITestCase
Expand Down Expand Up @@ -259,6 +261,29 @@ def test_null_ens_registry_address(self) -> None:
self.assertEqual(response.json()["ensRegistryAddress"], None)


class ChainCurrencyLogoTests(APITestCase):
def test_image_max_size_validation(self) -> None:
chain = ChainFactory.create(
currency_logo_uri=factory.django.ImageField(width=512, height=512)
)

chain.full_clean() # should not rise any exception

def test_image_width_greater_than_512(self) -> None:
with self.assertRaises(ValidationError):
chain = ChainFactory.create(
currency_logo_uri=factory.django.ImageField(width=513, height=50)
)
chain.full_clean()

def test_image_height_greater_than_512(self) -> None:
with self.assertRaises(ValidationError):
chain = ChainFactory.create(
currency_logo_uri=factory.django.ImageField(width=50, height=513)
)
chain.full_clean()


class ChainGasPriceTests(APITestCase):
faker = Faker()

Expand Down

0 comments on commit cc40485

Please sign in to comment.