]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🐛 Fix `OAuth2PasswordRequestForm` and `OAuth2PasswordRequestFormStrict` fixed `grant_...
authorRahul Pai <50425728+skarfie123@users.noreply.github.com>
Thu, 30 Jan 2025 12:17:09 +0000 (12:17 +0000)
committerGitHub <noreply@github.com>
Thu, 30 Jan 2025 12:17:09 +0000 (12:17 +0000)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Alejandra <90076947+alejsdev@users.noreply.github.com>
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
Co-authored-by: svlandeg <svlandeg@github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
fastapi/security/oauth2.py
tests/test_security_oauth2.py
tests/test_security_oauth2_optional.py
tests/test_security_oauth2_optional_description.py
tests/test_tutorial/test_security/test_tutorial003.py
tests/test_tutorial/test_security/test_tutorial005.py

index 6adc55bfeb150bd9421a551acf388532d8b7320b..5ffad59862ba942a26dc27ce77c66578659918d3 100644 (file)
@@ -63,7 +63,7 @@ class OAuth2PasswordRequestForm:
         *,
         grant_type: Annotated[
             Union[str, None],
-            Form(pattern="password"),
+            Form(pattern="^password$"),
             Doc(
                 """
                 The OAuth2 spec says it is required and MUST be the fixed string
@@ -217,7 +217,7 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm):
         self,
         grant_type: Annotated[
             str,
-            Form(pattern="password"),
+            Form(pattern="^password$"),
             Doc(
                 """
                 The OAuth2 spec says it is required and MUST be the fixed string
index 7d914d03452f674b6fdb34591bf5e0a00ddc4574..2b7e3457a9ded124b0add42573a5fa9e3c1270b7 100644 (file)
@@ -1,3 +1,4 @@
+import pytest
 from dirty_equals import IsDict
 from fastapi import Depends, FastAPI, Security
 from fastapi.security import OAuth2, OAuth2PasswordRequestFormStrict
@@ -137,10 +138,18 @@ def test_strict_login_no_grant_type():
     )
 
 
-def test_strict_login_incorrect_grant_type():
+@pytest.mark.parametrize(
+    argnames=["grant_type"],
+    argvalues=[
+        pytest.param("incorrect", id="incorrect value"),
+        pytest.param("passwordblah", id="password with suffix"),
+        pytest.param("blahpassword", id="password with prefix"),
+    ],
+)
+def test_strict_login_incorrect_grant_type(grant_type: str):
     response = client.post(
         "/login",
-        data={"username": "johndoe", "password": "secret", "grant_type": "incorrect"},
+        data={"username": "johndoe", "password": "secret", "grant_type": grant_type},
     )
     assert response.status_code == 422
     assert response.json() == IsDict(
@@ -149,9 +158,9 @@ def test_strict_login_incorrect_grant_type():
                 {
                     "type": "string_pattern_mismatch",
                     "loc": ["body", "grant_type"],
-                    "msg": "String should match pattern 'password'",
-                    "input": "incorrect",
-                    "ctx": {"pattern": "password"},
+                    "msg": "String should match pattern '^password$'",
+                    "input": grant_type,
+                    "ctx": {"pattern": "^password$"},
                 }
             ]
         }
@@ -161,9 +170,9 @@ def test_strict_login_incorrect_grant_type():
             "detail": [
                 {
                     "loc": ["body", "grant_type"],
-                    "msg": 'string does not match regex "password"',
+                    "msg": 'string does not match regex "^password$"',
                     "type": "value_error.str.regex",
-                    "ctx": {"pattern": "password"},
+                    "ctx": {"pattern": "^password$"},
                 }
             ]
         }
@@ -248,7 +257,7 @@ def test_openapi_schema():
                     "properties": {
                         "grant_type": {
                             "title": "Grant Type",
-                            "pattern": "password",
+                            "pattern": "^password$",
                             "type": "string",
                         },
                         "username": {"title": "Username", "type": "string"},
index 0da3b911e8467359b6ea1b4942398e574d27677f..046ac57637dfcea79c74dc045f90c8ade16ac5af 100644 (file)
@@ -1,5 +1,6 @@
 from typing import Optional
 
+import pytest
 from dirty_equals import IsDict
 from fastapi import Depends, FastAPI, Security
 from fastapi.security import OAuth2, OAuth2PasswordRequestFormStrict
@@ -141,10 +142,18 @@ def test_strict_login_no_grant_type():
     )
 
 
-def test_strict_login_incorrect_grant_type():
+@pytest.mark.parametrize(
+    argnames=["grant_type"],
+    argvalues=[
+        pytest.param("incorrect", id="incorrect value"),
+        pytest.param("passwordblah", id="password with suffix"),
+        pytest.param("blahpassword", id="password with prefix"),
+    ],
+)
+def test_strict_login_incorrect_grant_type(grant_type: str):
     response = client.post(
         "/login",
-        data={"username": "johndoe", "password": "secret", "grant_type": "incorrect"},
+        data={"username": "johndoe", "password": "secret", "grant_type": grant_type},
     )
     assert response.status_code == 422
     assert response.json() == IsDict(
@@ -153,9 +162,9 @@ def test_strict_login_incorrect_grant_type():
                 {
                     "type": "string_pattern_mismatch",
                     "loc": ["body", "grant_type"],
-                    "msg": "String should match pattern 'password'",
-                    "input": "incorrect",
-                    "ctx": {"pattern": "password"},
+                    "msg": "String should match pattern '^password$'",
+                    "input": grant_type,
+                    "ctx": {"pattern": "^password$"},
                 }
             ]
         }
@@ -165,9 +174,9 @@ def test_strict_login_incorrect_grant_type():
             "detail": [
                 {
                     "loc": ["body", "grant_type"],
-                    "msg": 'string does not match regex "password"',
+                    "msg": 'string does not match regex "^password$"',
                     "type": "value_error.str.regex",
-                    "ctx": {"pattern": "password"},
+                    "ctx": {"pattern": "^password$"},
                 }
             ]
         }
@@ -252,7 +261,7 @@ def test_openapi_schema():
                     "properties": {
                         "grant_type": {
                             "title": "Grant Type",
-                            "pattern": "password",
+                            "pattern": "^password$",
                             "type": "string",
                         },
                         "username": {"title": "Username", "type": "string"},
index 85a9f9b3910358773f5f16188f42fb9be3a31e9f..629cddca2f1a1c1abb854b1b8c580da6788eebea 100644 (file)
@@ -1,5 +1,6 @@
 from typing import Optional
 
+import pytest
 from dirty_equals import IsDict
 from fastapi import Depends, FastAPI, Security
 from fastapi.security import OAuth2, OAuth2PasswordRequestFormStrict
@@ -142,10 +143,18 @@ def test_strict_login_no_grant_type():
     )
 
 
-def test_strict_login_incorrect_grant_type():
+@pytest.mark.parametrize(
+    argnames=["grant_type"],
+    argvalues=[
+        pytest.param("incorrect", id="incorrect value"),
+        pytest.param("passwordblah", id="password with suffix"),
+        pytest.param("blahpassword", id="password with prefix"),
+    ],
+)
+def test_strict_login_incorrect_grant_type(grant_type: str):
     response = client.post(
         "/login",
-        data={"username": "johndoe", "password": "secret", "grant_type": "incorrect"},
+        data={"username": "johndoe", "password": "secret", "grant_type": grant_type},
     )
     assert response.status_code == 422
     assert response.json() == IsDict(
@@ -154,9 +163,9 @@ def test_strict_login_incorrect_grant_type():
                 {
                     "type": "string_pattern_mismatch",
                     "loc": ["body", "grant_type"],
-                    "msg": "String should match pattern 'password'",
-                    "input": "incorrect",
-                    "ctx": {"pattern": "password"},
+                    "msg": "String should match pattern '^password$'",
+                    "input": grant_type,
+                    "ctx": {"pattern": "^password$"},
                 }
             ]
         }
@@ -166,9 +175,9 @@ def test_strict_login_incorrect_grant_type():
             "detail": [
                 {
                     "loc": ["body", "grant_type"],
-                    "msg": 'string does not match regex "password"',
+                    "msg": 'string does not match regex "^password$"',
                     "type": "value_error.str.regex",
-                    "ctx": {"pattern": "password"},
+                    "ctx": {"pattern": "^password$"},
                 }
             ]
         }
@@ -253,7 +262,7 @@ def test_openapi_schema():
                     "properties": {
                         "grant_type": {
                             "title": "Grant Type",
-                            "pattern": "password",
+                            "pattern": "^password$",
                             "type": "string",
                         },
                         "username": {"title": "Username", "type": "string"},
index 7a4c99401bf2f1c9a6be183cf9f2fa050e298d3f..37fc2618fbc88365e83bccf8ad8249553e11cf49 100644 (file)
@@ -149,7 +149,7 @@ def test_openapi_schema(client: TestClient):
                             {
                                 "title": "Grant Type",
                                 "anyOf": [
-                                    {"pattern": "password", "type": "string"},
+                                    {"pattern": "^password$", "type": "string"},
                                     {"type": "null"},
                                 ],
                             }
@@ -158,7 +158,7 @@ def test_openapi_schema(client: TestClient):
                             # TODO: remove when deprecating Pydantic v1
                             {
                                 "title": "Grant Type",
-                                "pattern": "password",
+                                "pattern": "^password$",
                                 "type": "string",
                             }
                         ),
index c7f791b033a9753aa60fd04ae04cd95a089aeda2..88c3d7815726a0e4c37a6a32ea9ab54cb55a8cb0 100644 (file)
@@ -363,7 +363,7 @@ def test_openapi_schema(mod: ModuleType):
                             {
                                 "title": "Grant Type",
                                 "anyOf": [
-                                    {"pattern": "password", "type": "string"},
+                                    {"pattern": "^password$", "type": "string"},
                                     {"type": "null"},
                                 ],
                             }
@@ -372,7 +372,7 @@ def test_openapi_schema(mod: ModuleType):
                             # TODO: remove when deprecating Pydantic v1
                             {
                                 "title": "Grant Type",
-                                "pattern": "password",
+                                "pattern": "^password$",
                                 "type": "string",
                             }
                         ),