@@ -210,59 +210,76 @@ class JiraCookieAuth(AuthBase):
210210 """Jira Cookie Authentication
211211
212212 Allows using cookie authentication as described by
213- https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-cookie-based-authentication
214-
213+ https://developer.atlassian.com/server/jira/platform/cookie-based-authentication/
215214 """
216215
217216 def __init__ (
218- self , session : ResilientSession , _get_session : Callable , auth : Tuple [str , str ]
217+ self , session : ResilientSession , session_api_url : str , auth : Tuple [str , str ]
219218 ):
220219 """Cookie Based Authentication
221220
222221 Args:
223222 session (ResilientSession): The Session object to communicate with the API.
224- _get_session (Callable ): The function that returns a :py_class:``User``
225- auth (Tuple[str, str]): The username, password tuple
223+ session_api_url (str ): The session api url to use.
224+ auth (Tuple[str, str]): The username, password tuple.
226225 """
226+
227227 self ._session = session
228- self ._get_session = _get_session
228+ self ._session_api_url = session_api_url # e.g ."/rest/auth/1/session"
229229 self .__auth = auth
230+ self ._retry_counter_401 = 0
231+ self ._max_allowed_401_retries = 1 # 401 aren't recoverable with retries really
232+
233+ @property
234+ def cookies (self ):
235+ return self ._session .cookies
236+
237+ def _increment_401_retry_counter (self ):
238+ self ._retry_counter_401 += 1
239+
240+ def _reset_401_retry_counter (self ):
241+ self ._retry_counter_401 = 0
230242
231- def handle_401 (self , response , ** kwargs ):
232- if response .status_code != 401 :
233- return response
234- self .init_session ()
235- response = self .process_original_request (response .request .copy ())
243+ def __call__ (self , request : requests .PreparedRequest ):
244+ request .register_hook ("response" , self .handle_401 )
245+ return request
246+
247+ def init_session (self ):
248+ """Initialise the Session object's cookies, so we can use the session cookie."""
249+ username , password = self .__auth
250+ authentication_data = {"username" : username , "password" : password }
251+ r = self ._session .post ( # this also goes through the handle_401() hook
252+ self ._session_api_url , data = json .dumps (authentication_data )
253+ )
254+ r .raise_for_status ()
255+
256+ def handle_401 (self , response : requests .Response , ** kwargs ):
257+ """Refresh cookies if the session cookie has expired. Then retry the request."""
258+ if (
259+ response .status_code == 401
260+ and self ._retry_counter_401 < self ._max_allowed_401_retries
261+ ):
262+ LOG .info ("Trying to refresh the cookie auth session..." )
263+ self ._increment_401_retry_counter ()
264+ self .init_session ()
265+ response = self .process_original_request (response .request .copy ())
266+ self ._reset_401_retry_counter ()
236267 return response
237268
238- def process_original_request (self , original_request ):
269+ def process_original_request (self , original_request : requests . PreparedRequest ):
239270 self .update_cookies (original_request )
240271 return self .send_request (original_request )
241272
242- def update_cookies (self , original_request ):
273+ def update_cookies (self , original_request : requests . PreparedRequest ):
243274 # Cookie header needs first to be deleted for the header to be updated using
244275 # the prepare_cookies method. See request.PrepareRequest.prepare_cookies
245276 if "Cookie" in original_request .headers :
246277 del original_request .headers ["Cookie" ]
247278 original_request .prepare_cookies (self .cookies )
248279
249- def init_session (self ):
250- self .start_session ()
251-
252- def __call__ (self , request ):
253- request .register_hook ("response" , self .handle_401 )
254- return request
255-
256- def send_request (self , request ):
280+ def send_request (self , request : requests .PreparedRequest ):
257281 return self ._session .send (request )
258282
259- @property
260- def cookies (self ):
261- return self ._session .cookies
262-
263- def start_session (self ):
264- self ._get_session (self .__auth )
265-
266283
267284class TokenAuth (AuthBase ):
268285 """Bearer Token Authentication"""
@@ -571,8 +588,17 @@ def _create_cookie_auth(
571588 auth : Tuple [str , str ],
572589 timeout : Optional [Union [Union [float , int ], Tuple [float , float ]]],
573590 ):
591+ warnings .warn (
592+ "Use OAuth or Token based authentication "
593+ + "instead of Cookie based Authentication." ,
594+ DeprecationWarning ,
595+ )
574596 self ._session = ResilientSession (timeout = timeout )
575- self ._session .auth = JiraCookieAuth (self ._session , self .session , auth )
597+ self ._session .auth = JiraCookieAuth (
598+ session = self ._session ,
599+ session_api_url = "{server}{auth_url}" .format (** self ._options ),
600+ auth = auth ,
601+ )
576602
577603 def _check_update_ (self ):
578604 """Check if the current version of the library is outdated."""
0 commit comments