Skip to content

Commit 8f508d5

Browse files
author
IndominusByte
committed
add test to cookie until optional protected
1 parent 3cc9124 commit 8f508d5

File tree

3 files changed

+256
-0
lines changed

3 files changed

+256
-0
lines changed

tests/test_cookies.py

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
import pytest
2+
from fastapi_jwt_auth import AuthJWT
3+
from fastapi_jwt_auth.exceptions import AuthJWTException
4+
from fastapi import FastAPI, Request, Depends
5+
from fastapi.responses import JSONResponse
6+
from fastapi.testclient import TestClient
7+
8+
@pytest.fixture(scope='function')
9+
def client():
10+
app = FastAPI()
11+
12+
@app.exception_handler(AuthJWTException)
13+
def authjwt_exception_handler(request: Request, exc: AuthJWTException):
14+
return JSONResponse(
15+
status_code=exc.status_code,
16+
content={"detail": exc.message}
17+
)
18+
19+
@app.get('/all-token')
20+
def all_token(Authorize: AuthJWT = Depends()):
21+
access_token = Authorize.create_access_token(subject=1)
22+
refresh_token = Authorize.create_refresh_token(subject=1)
23+
Authorize.set_access_cookies(access_token)
24+
Authorize.set_refresh_cookies(refresh_token)
25+
return {"msg":"all token"}
26+
27+
@app.get('/access-token')
28+
def access_token(Authorize: AuthJWT = Depends()):
29+
access_token = Authorize.create_access_token(subject=1)
30+
Authorize.set_access_cookies(access_token)
31+
return {"msg":"access token"}
32+
33+
@app.get('/refresh-token')
34+
def refresh_token(Authorize: AuthJWT = Depends()):
35+
refresh_token = Authorize.create_refresh_token(subject=1)
36+
Authorize.set_refresh_cookies(refresh_token)
37+
return {"msg":"refresh token"}
38+
39+
@app.get('/unset-all-token')
40+
def unset_all_token(Authorize: AuthJWT = Depends()):
41+
Authorize.unset_jwt_cookies()
42+
return {"msg":"unset all token"}
43+
44+
@app.get('/unset-access-token')
45+
def unset_access_token(Authorize: AuthJWT = Depends()):
46+
Authorize.unset_access_cookies()
47+
return {"msg":"unset access token"}
48+
49+
@app.get('/unset-refresh-token')
50+
def unset_refresh_token(Authorize: AuthJWT = Depends()):
51+
Authorize.unset_refresh_cookies()
52+
return {"msg":"unset refresh token"}
53+
54+
@app.post('/jwt-optional')
55+
def jwt_optional(Authorize: AuthJWT = Depends()):
56+
Authorize.jwt_optional()
57+
return {"hello": Authorize.get_jwt_subject()}
58+
59+
client = TestClient(app)
60+
return client
61+
62+
@pytest.mark.parametrize(
63+
"url",["/access-token","/refresh-token","/unset-access-token","/unset-refresh-token"]
64+
)
65+
def test_warning_if_cookies_not_in_token_location(url,client):
66+
@AuthJWT.load_config
67+
def get_secret_key():
68+
return [("authjwt_secret_key","secret")]
69+
70+
with pytest.raises(RuntimeWarning,match=r"authjwt_token_location"):
71+
client.get(url)
72+
73+
def test_set_cookie_not_valid_type_max_age(Authorize):
74+
@AuthJWT.load_config
75+
def get_cookie_location():
76+
return [("authjwt_token_location",{'cookies'}),("authjwt_secret_key","secret")]
77+
78+
token = Authorize.create_access_token(subject=1)
79+
80+
with pytest.raises(TypeError,match=r"max_age"):
81+
Authorize.set_access_cookies(token,max_age="string")
82+
83+
with pytest.raises(TypeError,match=r"max_age"):
84+
Authorize.set_refresh_cookies(token,max_age="string")
85+
86+
@pytest.mark.parametrize("url",["/access-token","/refresh-token"])
87+
def test_set_cookie_csrf_protect_false(url,client):
88+
@AuthJWT.load_config
89+
def get_cookie_location():
90+
return [
91+
("authjwt_token_location",{'cookies'}),
92+
("authjwt_secret_key","secret"),
93+
("authjwt_cookie_csrf_protect",False)
94+
]
95+
96+
cookie_key = url.split("-")[0][1:]
97+
response = client.get(url)
98+
assert response.cookies.get("csrf_{}_token".format(cookie_key)) is None
99+
100+
@pytest.mark.parametrize("url",["/access-token","/refresh-token"])
101+
def test_set_cookie_csrf_protect_true(url,client):
102+
@AuthJWT.load_config
103+
def get_cookie_location():
104+
return [("authjwt_token_location",{'cookies'}),("authjwt_secret_key","secret")]
105+
106+
cookie_key = url.split("-")[0][1:]
107+
response = client.get(url)
108+
assert response.cookies.get("csrf_{}_token".format(cookie_key)) is not None
109+
110+
def test_unset_all_cookie(client):
111+
@AuthJWT.load_config
112+
def get_cookie_location():
113+
return [("authjwt_token_location",{'cookies'}),("authjwt_secret_key","secret")]
114+
115+
response = client.get('/all-token')
116+
assert response.cookies.get("access_token_cookie") is not None
117+
assert response.cookies.get("csrf_access_token") is not None
118+
119+
assert response.cookies.get("refresh_token_cookie") is not None
120+
assert response.cookies.get("csrf_refresh_token") is not None
121+
122+
response = client.get('/unset-all-token')
123+
124+
assert response.cookies.get("access_token_cookie") is None
125+
assert response.cookies.get("csrf_access_token") is None
126+
127+
assert response.cookies.get("refresh_token_cookie") is None
128+
assert response.cookies.get("csrf_refresh_token") is None
129+
130+
def test_custom_cookie_key(client):
131+
@AuthJWT.load_config
132+
def get_cookie_location():
133+
return [
134+
("authjwt_token_location",{'cookies'}),
135+
("authjwt_secret_key","secret"),
136+
("authjwt_access_cookie_key","access_cookie"),
137+
("authjwt_refresh_cookie_key","refresh_cookie"),
138+
("authjwt_access_csrf_cookie_key","csrf_access"),
139+
("authjwt_refresh_csrf_cookie_key","csrf_refresh")
140+
]
141+
142+
response = client.get('/all-token')
143+
assert response.cookies.get("access_cookie") is not None
144+
assert response.cookies.get("csrf_access") is not None
145+
146+
assert response.cookies.get("refresh_cookie") is not None
147+
assert response.cookies.get("csrf_refresh") is not None
148+
149+
response = client.get('/unset-all-token')
150+
151+
assert response.cookies.get("access_cookie") is None
152+
assert response.cookies.get("csrf_access") is None
153+
154+
assert response.cookies.get("refresh_cookie") is None
155+
assert response.cookies.get("csrf_refresh") is None
156+
157+
def test_cookie_optional_protected(client):
158+
@AuthJWT.load_config
159+
def get_cookie_location():
160+
return [("authjwt_token_location",{'cookies'}),("authjwt_secret_key","secret")]
161+
162+
url = '/jwt-optional'
163+
# without token
164+
response = client.post(url)
165+
assert response.status_code == 200
166+
assert response.json() == {'hello': None}
167+
168+
# change request methods and not check csrf token
169+
@AuthJWT.load_config
170+
def change_request_methods():
171+
return [
172+
("authjwt_csrf_methods",{"GET"}),
173+
("authjwt_token_location",{'cookies'}),
174+
("authjwt_secret_key","secret")
175+
]
176+
177+
client.get('/access-token')
178+
response = client.post(url)
179+
assert response.status_code == 200
180+
assert response.json() == {'hello': 1}
181+
182+
# change csrf protect to False not check csrf token
183+
@AuthJWT.load_config
184+
def change_request_csrf_protect_to_false():
185+
return [
186+
("authjwt_csrf_methods",{'POST','PUT','PATCH','DELETE'}),
187+
("authjwt_token_location",{'cookies'}),
188+
("authjwt_secret_key","secret"),
189+
("authjwt_cookie_csrf_protect",False)
190+
]
191+
192+
client.get('/access-token')
193+
response = client.post(url)
194+
assert response.status_code == 200
195+
assert response.json() == {'hello': 1}
196+
197+
# missing csrf token
198+
@AuthJWT.load_config
199+
def change_csrf_protect_to_true():
200+
return [
201+
("authjwt_token_location",{'cookies'}),
202+
("authjwt_secret_key","secret"),
203+
("authjwt_cookie_csrf_protect",True)
204+
]
205+
206+
res = client.get('/access-token')
207+
csrf_token = res.cookies.get("csrf_access_token")
208+
209+
response = client.post(url)
210+
assert response.status_code == 401
211+
assert response.json() == {'detail': 'Missing CSRF Token'}
212+
213+
# csrf token do not match
214+
response = client.post(url,headers={"X-CSRF-Token":"invalid"})
215+
assert response.status_code == 401
216+
assert response.json() == {'detail': 'CSRF double submit tokens do not match'}
217+
218+
response = client.post(url,headers={"X-CSRF-Token": csrf_token})
219+
assert response.status_code == 200
220+
assert response.json() == {'hello': 1}
221+
222+
# missing claim csrf in token
223+
@AuthJWT.load_config
224+
def change_request_csrf_protect_to_falsee():
225+
return [
226+
("authjwt_token_location",{'cookies'}),
227+
("authjwt_secret_key","secret"),
228+
("authjwt_cookie_csrf_protect",False)
229+
]
230+
231+
client.get('/access-token')
232+
233+
@AuthJWT.load_config
234+
def change_request_csrf_protect_to_truee():
235+
return [("authjwt_token_location",{'cookies'}),("authjwt_secret_key","secret")]
236+
237+
response = client.post(url,headers={"X-CSRF-Token":"invalid"})
238+
assert response.status_code == 422
239+
assert response.json() == {'detail': 'Missing claim: csrf'}
240+
241+
# custom csrf header name and cookie key
242+
@AuthJWT.load_config
243+
def custom_header_name_cookie_key():
244+
return [
245+
("authjwt_token_location",{'cookies'}),
246+
("authjwt_secret_key","secret"),
247+
("authjwt_access_cookie_key","access_cookie"),
248+
("authjwt_access_csrf_header_name","X-CSRF")
249+
]
250+
251+
res = client.get('/access-token')
252+
csrf_token = res.cookies.get("csrf_access_token")
253+
254+
response = client.post(url,headers={"X-CSRF": csrf_token})
255+
assert response.status_code == 200
256+
assert response.json() == {'hello': 1}
File renamed without changes.

tests/test_token_multiple_locations.py

Whitespace-only changes.

0 commit comments

Comments
 (0)