mirror of https://github.com/tiangolo/fastapi.git
Handle mistakes when wrong value is passed to `scopes` or `oauth_scopes`
This commit is contained in:
parent
73fd05ccf0
commit
ed8040aa98
|
|
@ -2453,8 +2453,29 @@ def Security( # noqa: N802
|
|||
stacklevel=2,
|
||||
)
|
||||
|
||||
# Handle case when `scopes="function"` is mistakenly used instead of `scope="function"`
|
||||
if isinstance(scopes, str) and (scopes in ("function", "request")):
|
||||
raise FastAPIError(
|
||||
"Invalid value for the 'scopes' parameter in Security(). "
|
||||
"Expected a sequence of strings (e.g., ['admin', 'user']), but received "
|
||||
"a single string. "
|
||||
f'Did you mean to use scope="{scopes}" to specify when the exit code '
|
||||
"of dependencies with yield should run? "
|
||||
)
|
||||
|
||||
oauth_scopes_param = "oauth_scopes" if (oauth_scopes is not None) else "scopes"
|
||||
oauth_scopes = oauth_scopes or scopes
|
||||
|
||||
# Handle case when single string is passed to `scopes` or `oauth_scopes` instead of
|
||||
# a list of strings
|
||||
if isinstance(oauth_scopes, str):
|
||||
raise FastAPIError(
|
||||
f"Invalid value for the '{oauth_scopes_param}' parameter in Security(). "
|
||||
"Expected a sequence of strings (e.g., ['admin', 'user']), but received a "
|
||||
"single string. Wrap it in a list: oauth_scopes=['your_scope'] instead of "
|
||||
"oauth_scopes='your_scope'."
|
||||
)
|
||||
|
||||
return params.Security(
|
||||
dependency=dependency,
|
||||
oauth_scopes=oauth_scopes,
|
||||
|
|
|
|||
|
|
@ -3,24 +3,35 @@ from fastapi import Security
|
|||
from fastapi.exceptions import FastAPIError
|
||||
|
||||
|
||||
def test_pass_single_str():
|
||||
@pytest.mark.parametrize("parameter_name", ["scopes", "oauth_scopes"])
|
||||
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
|
||||
def test_pass_single_str(parameter_name: str):
|
||||
"""
|
||||
Test passing single string instead of list of strings to `scopes` or `oauth_scopes`.
|
||||
"""
|
||||
|
||||
with pytest.raises(FastAPIError) as exc_info:
|
||||
Security(dependency=lambda: None, scopes="admin")
|
||||
Security(dependency=lambda: None, **{parameter_name: "admin"})
|
||||
|
||||
assert str(exc_info.value) == (
|
||||
"Invalid value for `scopes` parameter in Security(). "
|
||||
f"Invalid value for the '{parameter_name}' parameter in Security(). "
|
||||
"Expected a sequence of strings (e.g., ['admin', 'user']), but received a single string. "
|
||||
"Wrap it in a list: scopes=['your_scope'] instead of scopes='your_scope'."
|
||||
"Wrap it in a list: oauth_scopes=['your_scope'] instead of oauth_scopes='your_scope'."
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", ["function", "request"])
|
||||
def test_pass_scope_instead_of_scopes(value: str):
|
||||
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
|
||||
def test_pass_scope_as_scopes(value: str):
|
||||
"""
|
||||
Test passing `scopes="function"` instead of `scope="function"` to `Security`.
|
||||
"""
|
||||
|
||||
with pytest.raises(FastAPIError) as exc_info:
|
||||
Security(dependency=lambda: None, scopes=value)
|
||||
|
||||
assert str(exc_info.value) == (
|
||||
"Invalid value for `scopes` parameter in Security(). "
|
||||
"You probably meant to use the `scope` parameter instead of `scopes`. "
|
||||
"Expected a sequence of strings (e.g., ['admin', 'user']), but received a single string."
|
||||
"Invalid value for the 'scopes' parameter in Security(). "
|
||||
"Expected a sequence of strings (e.g., ['admin', 'user']), but received a single string. "
|
||||
f'Did you mean to use scope="{value}" to specify when the exit code of dependencies with yield should run? '
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue