Fix the field binding in a signup endpoint
Your task
An AI built a FastAPI signup flow on a Pydantic model that included role, plan and is_active. The model checked types, so the team assumed the input was safe, and a user signed up as an admin. That is mass assignment: the server binds fields the client should never control. Your signup now binds only fields on an allowlist and refuses the whole request when the body names any other field.
An assistant wrote bind_signup_payload(payload, allowed_fields). It is in the editor. It has a bug. Find it and fix it.
Input and output:
payload: the request body as a list of entries, normally"key=value", like"email=a@b.com". An entry can also be a bare key with no=. The list can be empty.allowed_fields: the fields a client may set, in the order the output uses. It can hold blanks and repeats, or be empty.- Return either the binding, as
"field=value"pairs joined with;, or"rejected:"followed by the refused keys joined with,.
Rules the tests check:
- Trim each allowed field. Ignore blank ones and repeats. A field's first appearance sets its place in the order.
- For an entry with an
=, the key is the text before the first=, trimmed. The value is everything after that=, kept exactly as it is. - An entry with no
=is a key with an empty value. Its key is the whole entry, trimmed. - Skip an entry whose key is empty. Keys compare with case.
- Refuse every key that is not an allowed field.
- If any key was refused, return
"rejected:"and the refused keys, each once, sorted in ascending order by character code, joined with,. - Otherwise, when an allowed key appears more than once, its last value wins. Return
"field=value"for each allowed field the payload set, in allowlist order, joined with;. Leave out fields the payload did not set. With nothing to bind, return"".
Examples
bind_signup_payload(payload: list[str], allowed_fields: list[str]) -> strExample 1
Input
bind_signup_payload(["email=a@b.com", "password=hunter2"], ["email", "password"])Output
"email=a@b.com;password=hunter2"Example 2
Input
bind_signup_payload(["email=a@b.com", "password=hunter2", "role=admin", "plan=enterprise"], ["email", "password"])Output
"rejected:plan,role"Example 3
Input
bind_signup_payload(["password=x", "email=y"], ["email", "password"])Output
"email=y;password=x"