11import unittest
2+ import warnings
23from datetime import timedelta
34
45import simplekv .memory
@@ -14,23 +15,29 @@ def setUp(self):
1415 self .app = Flask (__name__ )
1516 self .app .secret_key = 'super=secret'
1617 JWTManager (self .app )
17- self .client = self .app .test_client ()
1818
1919 def test_default_configs (self ):
2020 with self .app .test_request_context ():
2121 self .assertEqual (config .token_location , ['headers' ])
22+ self .assertEqual (config .jwt_in_cookies , False )
23+ self .assertEqual (config .jwt_in_headers , True )
2224 self .assertEqual (config .header_name , 'Authorization' )
2325 self .assertEqual (config .header_type , 'Bearer' )
2426
25- self .assertEqual (config .cookie_secure , False )
2627 self .assertEqual (config .access_cookie_name , 'access_token_cookie' )
2728 self .assertEqual (config .refresh_cookie_name , 'refresh_token_cookie' )
2829 self .assertEqual (config .access_cookie_path , '/' )
2930 self .assertEqual (config .refresh_cookie_path , '/' )
31+ self .assertEqual (config .cookie_secure , False )
3032 self .assertEqual (config .session_cookie , True )
33+
3134 self .assertEqual (config .csrf_protect , False )
35+ self .assertEqual (config .csrf_request_methods , ['POST' , 'PUT' , 'PATCH' , 'DELETE' ])
36+ self .assertEqual (config .csrf_in_cookies , True )
3237 self .assertEqual (config .access_csrf_cookie_name , 'csrf_access_token' )
3338 self .assertEqual (config .refresh_csrf_cookie_name , 'csrf_refresh_token' )
39+ self .assertEqual (config .access_csrf_cookie_path , '/' )
40+ self .assertEqual (config .refresh_csrf_cookie_path , '/' )
3441 self .assertEqual (config .access_csrf_header_name , 'X-CSRF-TOKEN' )
3542 self .assertEqual (config .refresh_csrf_header_name , 'X-CSRF-TOKEN' )
3643
@@ -39,68 +46,159 @@ def test_default_configs(self):
3946 self .assertEqual (config .algorithm , 'HS256' )
4047 self .assertEqual (config .blacklist_enabled , False )
4148 self .assertEqual (config .blacklist_checks , 'refresh' )
49+ self .assertEqual (config .blacklist_access_tokens , False )
50+
51+ self .assertEqual (config .secret_key , self .app .secret_key )
52+ self .assertEqual (config .cookie_max_age , None )
4253
4354 with self .assertRaises (RuntimeError ):
44- self . assertEqual ( config .blacklist_store , None )
55+ config .blacklist_store
4556
4657 def test_override_configs (self ):
47- self .app .config ['JWT_TOKEN_LOCATION' ] = 'cookies'
48- self .app .config ['JWT_HEADER_NAME' ] = 'Auth'
49- self .app .config ['JWT_HEADER_TYPE' ] = 'JWT'
58+ sample_store = simplekv .memory .DictStore ()
59+
60+ self .app .config ['JWT_TOKEN_LOCATION' ] = ['cookies' ]
61+ self .app .config ['JWT_HEADER_NAME' ] = 'TestHeader'
62+ self .app .config ['JWT_HEADER_TYPE' ] = 'TestType'
5063
64+ self .app .config ['JWT_ACCESS_COOKIE_NAME' ] = 'new_access_cookie'
65+ self .app .config ['JWT_REFRESH_COOKIE_NAME' ] = 'new_refresh_cookie'
66+ self .app .config ['JWT_ACCESS_COOKIE_PATH' ] = '/access/path'
67+ self .app .config ['JWT_REFRESH_COOKIE_PATH' ] = '/refresh/path'
5168 self .app .config ['JWT_COOKIE_SECURE' ] = True
52- self .app .config ['JWT_ACCESS_COOKIE_NAME' ] = 'banana1'
53- self .app .config ['JWT_REFRESH_COOKIE_NAME' ] = 'banana2'
54- self .app .config ['JWT_ACCESS_COOKIE_PATH' ] = '/banana/'
55- self .app .config ['JWT_REFRESH_COOKIE_PATH' ] = '/banana2/'
5669 self .app .config ['JWT_SESSION_COOKIE' ] = False
70+
5771 self .app .config ['JWT_COOKIE_CSRF_PROTECT' ] = True
58- self .app .config ['JWT_ACCESS_CSRF_COOKIE_NAME' ] = 'banana1a'
59- self .app .config ['JWT_REFRESH_CSRF_COOKIE_NAME' ] = 'banana2a'
60- self .app .config ['JWT_ACCESS_CSRF_HEADER_NAME' ] = 'bananaaaa'
61- self .app .config ['JWT_REFRESH_CSRF_HEADER_NAME' ] = 'bananaaaa2'
72+ self .app .config ['JWT_CSRF_METHODS' ] = ['GET' ]
73+ self .app .config ['JWT_CSRF_IN_COOKIES' ] = False
74+ self .app .config ['JWT_ACCESS_CSRF_COOKIE_NAME' ] = 'access_csrf_cookie'
75+ self .app .config ['JWT_REFRESH_CSRF_COOKIE_NAME' ] = 'refresh_csrf_cookie'
76+ self .app .config ['JWT_ACCESS_CSRF_COOKIE_PATH' ] = '/csrf/access/path'
77+ self .app .config ['JWT_REFRESH_CSRF_COOKIE_PATH' ] = '/csrf/refresh/path'
78+ self .app .config ['JWT_ACCESS_CSRF_HEADER_NAME' ] = 'X-ACCESS-CSRF'
79+ self .app .config ['JWT_REFRESH_CSRF_HEADER_NAME' ] = 'X-REFRESH-CSRF'
6280
6381 self .app .config ['JWT_ACCESS_TOKEN_EXPIRES' ] = timedelta (minutes = 5 )
64- self .app .config ['JWT_REFRESH_TOKEN_EXPIRES' ] = timedelta (days = 7 )
82+ self .app .config ['JWT_REFRESH_TOKEN_EXPIRES' ] = timedelta (days = 5 )
6583 self .app .config ['JWT_ALGORITHM' ] = 'HS512'
84+
6685 self .app .config ['JWT_BLACKLIST_ENABLED' ] = True
67- self .app .config ['JWT_BLACKLIST_STORE' ] = simplekv . memory . DictStore ()
86+ self .app .config ['JWT_BLACKLIST_STORE' ] = sample_store
6887 self .app .config ['JWT_BLACKLIST_TOKEN_CHECKS' ] = 'all'
6988
89+ self .app .secret_key = 'banana'
90+
7091 with self .app .test_request_context ():
7192 self .assertEqual (config .token_location , ['cookies' ])
72- self .assertEqual (config .header_name , 'Auth' )
73- self .assertEqual (config .header_type , 'JWT' )
74-
93+ self .assertEqual (config .jwt_in_cookies , True )
94+ self .assertEqual (config .jwt_in_headers , False )
95+ self .assertEqual (config .header_name , 'TestHeader' )
96+ self .assertEqual (config .header_type , 'TestType' )
97+
98+ self .assertEqual (config .access_cookie_name , 'new_access_cookie' )
99+ self .assertEqual (config .refresh_cookie_name , 'new_refresh_cookie' )
100+ self .assertEqual (config .access_cookie_path , '/access/path' )
101+ self .assertEqual (config .refresh_cookie_path , '/refresh/path' )
75102 self .assertEqual (config .cookie_secure , True )
76- self .assertEqual (config .access_cookie_name , 'banana1' )
77- self .assertEqual (config .refresh_cookie_name , 'banana2' )
78- self .assertEqual (config .access_cookie_path , '/banana/' )
79- self .assertEqual (config .refresh_cookie_path , '/banana2/' )
80103 self .assertEqual (config .session_cookie , False )
104+
81105 self .assertEqual (config .csrf_protect , True )
82- self .assertEqual (config .access_csrf_cookie_name , 'banana1a' )
83- self .assertEqual (config .refresh_csrf_cookie_name , 'banana2a' )
84- self .assertEqual (config .access_csrf_header_name , 'bananaaaa' )
85- self .assertEqual (config .refresh_csrf_header_name , 'bananaaaa2' )
106+ self .assertEqual (config .csrf_request_methods , ['GET' ])
107+ self .assertEqual (config .csrf_in_cookies , False )
108+ self .assertEqual (config .access_csrf_cookie_name , 'access_csrf_cookie' )
109+ self .assertEqual (config .refresh_csrf_cookie_name , 'refresh_csrf_cookie' )
110+ self .assertEqual (config .access_csrf_cookie_path , '/csrf/access/path' )
111+ self .assertEqual (config .refresh_csrf_cookie_path , '/csrf/refresh/path' )
112+ self .assertEqual (config .access_csrf_header_name , 'X-ACCESS-CSRF' )
113+ self .assertEqual (config .refresh_csrf_header_name , 'X-REFRESH-CSRF' )
86114
87115 self .assertEqual (config .access_expires , timedelta (minutes = 5 ))
88- self .assertEqual (config .refresh_expires , timedelta (days = 7 ))
116+ self .assertEqual (config .refresh_expires , timedelta (days = 5 ))
89117 self .assertEqual (config .algorithm , 'HS512' )
118+
90119 self .assertEqual (config .blacklist_enabled , True )
120+ self .assertEqual (config .blacklist_store , sample_store )
91121 self .assertEqual (config .blacklist_checks , 'all' )
122+ self .assertEqual (config .blacklist_access_tokens , True )
92123
93- self .app .config ['JWT_TOKEN_LOCATION' ] = 'banana'
94- self .app .config ['JWT_HEADER_NAME' ] = ''
95- self .app .config ['JWT_ACCESS_TOKEN_EXPIRES' ] = 'banana'
96- self .app .config ['JWT_REFRESH_TOKEN_EXPIRES' ] = 'banana'
124+ self .assertEqual (config .secret_key , 'banana' )
125+ self .assertEqual (config .cookie_max_age , 2147483647 )
97126
127+ def test_invalid_config_options (self ):
98128 with self .app .test_request_context ():
129+ self .app .config ['JWT_TOKEN_LOCATION' ] = 'banana'
99130 with self .assertRaises (RuntimeError ):
100- config .header_name
131+ config .token_location
132+
133+ self .app .config ['JWT_TOKEN_LOCATION' ] = ['headers' , 'cookies' , 'banana' ]
134+ with self .assertRaises (RuntimeError ):
135+ config .token_location
136+
137+ self .app .config ['JWT_HEADER_NAME' ] = ''
138+ with self .app .test_request_context ():
139+ with self .assertRaises (RuntimeError ):
140+ config .header_name
141+
142+ self .app .config ['JWT_ACCESS_TOKEN_EXPIRES' ] = 'banana'
101143 with self .assertRaises (RuntimeError ):
102144 config .access_expires
145+
146+ self .app .config ['JWT_REFRESH_TOKEN_EXPIRES' ] = 'banana'
103147 with self .assertRaises (RuntimeError ):
104148 config .refresh_expires
149+
150+ self .app .config ['JWT_BLACKLIST_STORE' ] = {}
105151 with self .assertRaises (RuntimeError ):
106- config .token_location
152+ config .blacklist_store
153+
154+ self .app .config ['JWT_BLACKLIST_TOKEN_CHECKS' ] = 'banana'
155+ with self .assertRaises (RuntimeError ):
156+ config .blacklist_checks
157+
158+ self .app .secret_key = None
159+ with self .assertRaises (RuntimeError ):
160+ config .secret_key
161+
162+ self .app .secret_key = ''
163+ with self .assertRaises (RuntimeError ):
164+ config .secret_key
165+
166+ def test_depreciated_options (self ):
167+ self .app .config ['JWT_CSRF_HEADER_NAME' ] = 'Auth'
168+
169+ # Cause all warnings to always be triggered.
170+ warnings .simplefilter ("always" )
171+
172+ # Verify our warnings are thrown
173+ with self .app .test_request_context ():
174+ with warnings .catch_warnings (record = True ) as w :
175+ self .assertEqual (config .access_csrf_header_name , 'Auth' )
176+ self .assertEqual (config .refresh_csrf_header_name , 'Auth' )
177+ self .assertEqual (len (w ), 2 )
178+ self .assertEqual (w [0 ].category , DeprecationWarning )
179+ self .assertEqual (w [1 ].category , DeprecationWarning )
180+
181+ def test_special_config_options (self ):
182+ with self .app .test_request_context ():
183+ # Test changing strings to lists for JWT_TOKEN_LOCATIONS
184+ self .app .config ['JWT_TOKEN_LOCATION' ] = 'headers'
185+ self .assertEqual (config .token_location , ['headers' ])
186+ self .app .config ['JWT_TOKEN_LOCATION' ] = ['headers' ]
187+ self .assertEqual (config .token_location , ['headers' ])
188+ self .app .config ['JWT_TOKEN_LOCATION' ] = 'cookies'
189+ self .assertEqual (config .token_location , ['cookies' ])
190+ self .app .config ['JWT_TOKEN_LOCATION' ] = ['cookies' ]
191+ self .assertEqual (config .token_location , ['cookies' ])
192+ self .app .config ['JWT_TOKEN_LOCATION' ] = ['cookies' , 'headers' ]
193+ self .assertEqual (config .token_location , ['cookies' , 'headers' ])
194+
195+ # Test csrf protect options
196+ self .app .config ['JWT_TOKEN_LOCATION' ] = ['headers' ]
197+ self .app .config ['JWT_COOKIE_CSRF_PROTECT' ] = True
198+ self .assertEqual (config .csrf_protect , False )
199+ self .app .config ['JWT_TOKEN_LOCATION' ] = ['cookies' ]
200+ self .app .config ['JWT_COOKIE_CSRF_PROTECT' ] = True
201+ self .assertEqual (config .csrf_protect , True )
202+ self .app .config ['JWT_TOKEN_LOCATION' ] = ['cookies' ]
203+ self .app .config ['JWT_COOKIE_CSRF_PROTECT' ] = False
204+ self .assertEqual (config .csrf_protect , False )
0 commit comments