An AI assistant wrote the route the shop's admin uses to delete a product. Here is the AI's version:
app.MapDelete("/products/{id}", (int id, HttpRequest request) => {
var cmd = db.CreateCommand();
cmd.CommandText = "DELETE FROM products WHERE id = $id";
cmd.Parameters.AddWithValue("$id", id);
if (cmd.ExecuteNonQuery() == 0) {
return Results.Json(new { error = "Product not found" }, statusCode: 404);
}
return Results.StatusCode(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 products.
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 CurrentRole(request) reads the token from the Authorization header and gives that user's role from TOKENS, or null. Here is the first check on another route:
app.MapGet("/account", (HttpRequest request) => {
var role = CurrentRole(request);
if (role == null) {
return Results.Json(new { error = "Login required" }, statusCode: 401);
}
return Results.Json(new { 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 the MapDelete function. 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 the MapDelete function so only the admin can delete a product.
Hint
Both checks go before the DELETE: ExecuteNonQuery() saves it at once, and then 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.
