An AI assistant wrote the route the shop's admin uses to delete a product. Here is the AI's version:
@app.delete("/products/<int:product_id>")
def delete_product(product_id):
cursor = db.execute("DELETE FROM products WHERE id = ?", (product_id,))
db.commit()
if cursor.rowcount == 0:
return jsonify({"error": "Product not found"}), 404
return "", 204
Every line is right, and a quick try works. The hole is a line that isn't there: the route never asks who is calling, so anyone on the internet can delete every product.
A route that changes data checks the caller first, and there are two ways to refuse. 401 means "we don't know who you are": no token, or a token the shop never gave out. 403 Forbidden means "we know who you are, and you may not do this". The helper current_role() reads the token from the Authorization header and gives that user's role from TOKENS, or None. Here is the first check on another route:
@app.get("/account")
def account():
role = current_role()
if role is None:
return jsonify({"error": "Login required"}), 401
return jsonify({"role": role})
The tests run in this order, on one database:
DELETE /products/8 (no token) → 401 {"error": "Login required"}
DELETE /products/8 Bearer ana-token-123 → 403 {"error": "Admins only"}
GET /products/8 → 200 {"id": 8, "name": "Gift card", "price": 50, "category": null, "stock": 999}
DELETE /products/8 Bearer admin-token-456 → 204 (empty)
GET /products/8 → 404 {"error": "Product not found"}
DELETE /products/8 Bearer admin-token-456 → 404 {"error": "Product not found"}
DELETE /products/3 Bearer let-me-in → 401 {"error": "Login required"}
DELETE /products/99 (no token) → 401 {"error": "Login required"}
GET /products/3 → 200 {"id": 3, "name": "Lamp", "price": 29, "category": "home", "stock": 1}
Your task: rewrite delete_product. Delete the product and answer 204, or 404 if there was none. Then add the checks at the top: 401 {"error": "Login required"} when there is no role, and 403 {"error": "Admins only"} when the role isn't "admin".
Assignment
Follow the Coding Tutorial to rewrite delete_product so only the admin can delete a product.
Hint
Both checks go before the DELETE: once it runs and is committed, the product is gone, whatever you answer. The 401 check comes first, then role != "admin" for the 403.
Free plan: 30 tutor messages. PRO is unlimited.
