The shop now hands out keys to its staff too, for other jobs later. Adding products stays the owner's job. So a refused request can mean two different things, and HTTP has a status for each.
401 Unauthorized means "I don't know who you are": the key is missing, or it isn't one of the shop's keys. 403 Forbidden means "I know who you are, and you may not do this": the key is real, but its role isn't allowed. After a 401 a client should send a valid key; after a 403, trying again won't help.
A Map can map each valid key to its role. containsKey tells whether a key is in the map, and get gives the value stored for a key. Wrapping Map.of in a new HashMap<> lets the map answer false for null instead of throwing. Here with made-up keys for a music app:
static final Map<String, String> PLANS = new HashMap<>(Map.of("free-key-1", "free", "pro-key-2", "pro"));
System.out.println(PLANS.containsKey("pro-key-2")); // true
System.out.println(PLANS.containsKey(null)); // false
System.out.println(PLANS.get("pro-key-2")); // pro
These are the requests your code must answer:
POST /products {"name": "Vase", "price": 18} (no key) → 401 {"error": "Missing or unknown key"}
POST /products {"name": "Vase", "price": 18} X-Admin-Key: let-me-in → 401 {"error": "Missing or unknown key"}
POST /products {"name": "Vase", "price": 18} X-Admin-Key: staff-key-456 → 403 {"error": "Admins only"}
POST /products {"name": "Vase", "price": 18} X-Admin-Key: admin-key-123 → 201 {"id": 9, "name": "Vase", "price": 18}
GET /products/10 → 404 {"error": "Product not found"}Your task: replace ADMIN_KEY with a Map<String, String> API_KEYS that maps "admin-key-123" to "admin" and "staff-key-456" to "staff". In addProduct, answer 401 when API_KEYS doesn't contain the key, then 403 with {"error": "Admins only"} when its role isn't "admin".
Assignment
Follow the Coding Tutorial to tell an unknown caller (401) from a known caller who isn't allowed (403).
Hint
Keep the order: 401 first, then 403. For a missing key, API_KEYS.get(key) gives null, and calling .equals on null throws a NullPointerException. After the 401 check, every key that's left is in the map.
Free plan: 30 tutor messages. PRO is unlimited.
