Start learning free

LESSON 91 OF 188 · BACKEND: USERS AND SECURITY

Customers and Admins

Practice

So far every user is the same kind of user, so the shop can't tell its owner from a shopper. A role column fixes that: each user is a 'customer' or an 'admin', and only admins may add products.

A column with a DEFAULT fills itself in when an INSERT leaves it out. For example, an orders table could start every order as 'new', so an INSERT that gives only the user_id still gets a status:

db.execute("CREATE TABLE IF NOT EXISTS orders (id INTEGER PRIMARY KEY, user_id INTEGER NOT NULL, status TEXT NOT NULL DEFAULT 'new')")
db.execute("INSERT INTO orders (user_id) VALUES (?)", (2,))

There are two ways to say no. 401 means "I don't know who you are: log in". 403 Forbidden means "I know who you are, and you may not do this". A second decorator, admin_required, gives the 403. It goes below @login_required, which finds the user first and passes it on.

Nobody can sign up as an admin, so the shop creates its owner's account itself when it starts. Ana signs up after that, so she gets id 2:

POST /register  {"email": "ana@example.com", "password": "secret123"}  →  201  {"email": "ana@example.com", "id": 2}
GET /me  (Ana's token)  →  200  {"email": "ana@example.com", "id": 2, "role": "customer"}
POST /products  {"name": "Desk", "price": 120}  (Ana's token)  →  403  {"error": "Admins only"}
POST /products  {"name": "Desk", "price": 120}  (no token)  →  401  {"error": "Login required"}
POST /login  {"email": "admin@example.com", "password": "admin-pass-123"}  →  200  {"token": "…"}
GET /me  (admin's token)  →  200  {"email": "admin@example.com", "id": 1, "role": "admin"}
POST /products  {"name": "Desk", "price": 120}  (admin's token)  →  201  {"id": 9, "name": "Desk", "price": 120}

Your task: give the users table a role column that defaults to 'customer', create the admin account when the app starts, select the role in current_user, write the admin_required decorator, and put it on POST /products, below @login_required.


Assignment
Follow the Coding Tutorial to give every user a role and let only admins add products.


Hint
Inside SQL written in double quotes, the text 'customer' takes single quotes. Stack the decorators with @login_required first: admin_required needs the user it finds.


STEP 1 OF 12
    Ctrl + Enter to check