Проверка JSON для простого просмотра - PullRequest
0 голосов
/ 14 января 2020

У меня есть простое Django веб-приложение, которое я использую для регистрации личных расходов. Я начал писать новое представление, которое создаст веб-крючок для приема транзакций от моего банка Monzo. Поэтому каждый раз, когда на моем счете появляется новая транзакция, Monzo отправляет JSON с подробностями на указанный мной URL-адрес. И мое приложение должно сохранить эту транзакцию.

Поскольку это все, что происходит, всего лишь один веб-крючок, я решил не использовать каркас Django REST и просто создать представление, которое получает JSON от Банк и сохраняет транзакцию.

Банк повторно отправляет каждую транзакцию два раза. Один раз, когда транзакция впервые попадает на счет, а затем, как правило, второй раз, как только транзакция была рассчитана (выполнена). Так что мой взгляд проверит, существует ли транзакция, и затем либо создаст новую запись, либо обновит существующую.

До сих пор я написал только несколько строк кода и подтвердил, что JSON получен и можно получить в представлении.

Мой вопрос касается проверки. Какую проверку следует выполнить, чтобы убедиться, что JSON не содержит ничего опасного и безопасно для обработки с моей точки зрения?

Пример транзакции, которую банк отправит на мой webhook.

{
    "type": "transaction.created",
    "data": {
        "account_id": "acc_00008gju41AHyfLUzBUk8A",
        "amount": -350,
        "created": "2015-09-04T14:28:40Z",
        "currency": "GBP",
        "description": "Ozone Coffee Roasters",
        "id": "tx_00008zjky19HyFLAzlUk7t",
        "category": "eating_out",
        "is_load": false,
        "settled": "2015-09-05T14:28:40Z",
        "merchant": {
            "address": {
                "address": "98 Southgate Road",
                "city": "London",
                "country": "GB",
                "latitude": 51.54151,
                "longitude": -0.08482400000002599,
                "postcode": "N1 3JD",
                "region": "Greater London"
            },
            "created": "2015-08-22T12:20:18Z",
            "group_id": "grp_00008zIcpbBOaAr7TTP3sv",
            "id": "merch_00008zIcpbAKe8shBxXUtl",
            "logo": "https://pbs.twimg.com/profile_images/527043602623389696/68_SgUWJ.jpeg",
            "emoji": "?",
            "name": "The De Beauvoir Deli Co.",
            "category": "eating_out"
        }
    }
}

Это то, как далеко я продвинулся сегодня утром с моим кодом, так что не далеко, но вы можете видеть, куда я иду с этим.

@csrf_exempt
def index(request):
    data = json.loads(request.body)

    # Check if transaction already exists and if so then update.
    if Transaction.objects.filter(monzo_id=data['data']['id']).exists()
        transaction = Transaction.objects.filter(monzo_id=data['data']['id']) # Do I need to check there's only one record?
        transaction.data = data
        transaction.updated = datetime.datetime.now()
        transaction.settled = data['data']['settled']
        transaction.save()
    else:
        transaction = Transaction(
            created = datetime.datetime.now(),
            monzo_id = data['data']['settled']
            .... #More will go here...
            )
        transaction.save()

    #logger.warning(data['type'])
    #logger.warning(data['data']['merchant']['address']['city'])
    #logger.warning(data['data'])
    return render(request, 'template.html', {'content': data}) # Sending data to view just for debugging purposes

Мои модели.py:

from django.db import models

class Category(models.Model):
    name = models.CharField(max_length=250, null=False, blank=False)

class Merchant(models.Model):
    monzo_id = models.CharField(max_length=250)
    name = models.CharField(max_length=250, null=False, blank=False)
    category = models.ForeignKey(Category, on_delete=models.PROTECT)
    logo = models.URLField(max_length=250, null=True, blank=True) # Should this be URL field?
    data = models.TextField(blank = False, null=False)

class Transaction(models.Model):
    created = models.DateTimeField(null=False, blank=False)
    updated = models.DateTimeField(null=True, blank=True)
    account = # To be completed
    monzo_id = models.CharField(max_length=250)
    datetime = models.DateTimeField(null=False, blank=False)
    settled = models.DateTimeField(null=True, blank=True)
    amount = models.DecimalField(max_digits=8, decimal_places=2, null=False, blank=False)
    currency = models.CharField(max_length=3, null=False, blank=False)
    description = models.CharField(max_length=250, null=False, blank=False)
    is_load = models.BooleanField(default=False, null=True, blank=True)
    merchant_id = models.ForeignKey(Merchant, on_delete=models.PROTECT)
    data = models.TextField(blank = False, null=False)
...