Start learning free

LESSON 98 OF 188 · BACKEND: USERS AND SECURITY

Validate Everything

Practice

A client can send anything: an email without an @, a password of one letter, a price of -5, a price written as text. Today the shop stores all of it. A safe backend validates every value before it stores it.

When a value is wrong, the shop answers 400 Bad Request with a message and the name of the field that is wrong, so an app can show the message next to that box. Two Python tools help: isinstance tells a value's type, and split cuts a text into parts.

isinstance(120, int)       # True
isinstance("120", int)     # False: a text, even if it looks like a number
isinstance(None, str)      # False: that's what a missing field gives
"bo@shop.io".split("@")    # ["bo", "shop.io"]

Read fields with data.get(...): a missing field gives None instead of crashing with 500. And check every route that takes a value: a rule that one route forgets protects nothing.

POST /register  {"email": "ana.example.com", "password": "secret123"}  →  400  {"error": "Enter a valid email, like ana@example.com", "field": "email"}
POST /register  {"password": "secret123"}  →  400  {"error": "Enter a valid email, like ana@example.com", "field": "email"}
POST /register  {"email": "ana@example.com", "password": "123"}  →  400  {"error": "The password needs at least 8 characters", "field": "password"}
POST /register  {"email": "ana@example.com", "password": "secret123"}  →  201  {"email": "ana@example.com", "id": 2}
PUT /me/password  {"old_password": "secret123", "new_password": "abc"}  (Ana's token)  →  400  {"error": "The password needs at least 8 characters", "field": "new_password"}
POST /products  {"name": "Desk", "price": -5}  (admin's token)  →  400  {"error": "The price must be a whole number from 1 to 10000", "field": "price"}
POST /products  {"name": "Desk", "price": "120"}  (admin's token)  →  400  {"error": "The price must be a whole number from 1 to 10000", "field": "price"}
POST /products  {"name": "Desk", "price": 120}  (admin's token)  →  201  {"id": 9, "name": "Desk", "price": 120}

Your task: write two helpers, invalid(field, message) for the 400 answer and valid_email(email), then check the email and the password in register, the new password in change_password, and the price in add_product.


Assignment
Follow the Coding Tutorial to write the two helpers and add the four checks.


Hint
Put the isinstance test first in each if: or stops at the first true part, so len or count never runs on None. An email is valid when it is a text with exactly one @, no space, a name before the @ and a dot after it.


STEP 1 OF 11
    Ctrl + Enter to check