From 30c4349b01b2a063c3d889bbdd533609a2fd3a9a Mon Sep 17 00:00:00 2001 From: Leonardo Cavallucci Date: Wed, 23 Aug 2023 16:23:25 +0200 Subject: [PATCH] Add refresh_token API call (#139) --- changes/131.feature | 1 + taiga/client.py | 28 ++++++++++++ .../resources/auth_refresh_token_success.json | 4 ++ tests/test_auth.py | 45 +++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 changes/131.feature create mode 100644 tests/resources/auth_refresh_token_success.json diff --git a/changes/131.feature b/changes/131.feature new file mode 100644 index 0000000..64d0984 --- /dev/null +++ b/changes/131.feature @@ -0,0 +1 @@ +Add refresh_token API call diff --git a/taiga/client.py b/taiga/client.py index dbed11b..912674e 100644 --- a/taiga/client.py +++ b/taiga/client.py @@ -63,6 +63,7 @@ def __init__( ): self.host = host self.token = token + self.token_refresh = None self.token_type = token_type self.tls_verify = tls_verify self.auth_type = auth_type @@ -184,3 +185,30 @@ def auth_app(self, app_id, app_secret, auth_code, state=""): self.raw_request = RequestMaker("/api/v1", self.host, self.token, "Application", self.tls_verify) self._init_resources() + + def refresh_token(self, token_refresh=""): + """ + Refresh auth token. + + Passing a token_refresh will use passed token, otherwise it will try to use self.token_refresh. + + :param token_refresh: the refresh token to be used to refresh api token + """ + if not token_refresh: + if self.token_refresh: + token_refresh = self.token_refresh + else: + raise ValueError("Refresh token not set") + headers = {"Content-type": "application/json"} + payload = {"refresh": token_refresh} + try: + full_url = utils.urljoin(self.host, "/api/v1/auth/refresh") + response = requests.post(full_url, data=json.dumps(payload), headers=headers, verify=self.tls_verify) + except RequestException: + raise exceptions.TaigaRestException(full_url, 400, "NETWORK ERROR", "POST") + if response.status_code != 200: + raise exceptions.TaigaRestException(full_url, response.status_code, response.text, "POST") + self.token = response.json()["auth_token"] + self.token_refresh = response.json()["refresh"] + self.raw_request = RequestMaker("/api/v1", self.host, self.token, "Bearer", self.tls_verify) + self._init_resources() diff --git a/tests/resources/auth_refresh_token_success.json b/tests/resources/auth_refresh_token_success.json new file mode 100644 index 0000000..d86036e --- /dev/null +++ b/tests/resources/auth_refresh_token_success.json @@ -0,0 +1,4 @@ +{ + "auth_token": "newToken", + "refresh": "newRefreshToken" +} diff --git a/tests/test_auth.py b/tests/test_auth.py index a45cbad..8d08327 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -38,3 +38,48 @@ def test_auth_connection_error(self, requests_post): requests_post.side_effect = requests.RequestException() api = TaigaAPI(host="host") self.assertRaises(taiga.exceptions.TaigaRestException, api.auth, "valid_user", "valid_password") + + @patch("taiga.client.requests") + def test_refresh_token_not_success(self, requests): + requests.post.return_value = MockResponse(401, "Not allowed") + api = TaigaAPI(host="host") + self.assertRaises(taiga.exceptions.TaigaRestException, api.refresh_token, "testToken") + + @patch("taiga.client.requests.post") + def test_refresh_token_connection_error(self, requests_post): + requests_post.side_effect = requests.RequestException() + api = TaigaAPI(host="host") + self.assertRaises(taiga.exceptions.TaigaRestException, api.refresh_token, "testToken") + + def test_refresh_token_without_auth(self): + api = TaigaAPI(host="host") + self.assertRaises(ValueError, api.refresh_token) + + @patch("taiga.client.requests.post") + def test_refresh_token_passed_token(self, requests_post): + requests_post.return_value = MockResponse( + 200, create_mock_json("tests/resources/auth_refresh_token_success.json") + ) + api = TaigaAPI(host="host") + api.refresh_token("testToken") + requests_post.assert_called_with( + "host/api/v1/auth/refresh", + data='{"refresh": "testToken"}', + headers={"Content-type": "application/json"}, + verify=True, + ) + + @patch("taiga.client.requests.post") + def test_refresh_token_with_auth(self, requests_post): + requests_post.return_value = MockResponse(200, create_mock_json("tests/resources/auth_user_success.json")) + api = TaigaAPI(host="host") + api.auth("valid_user", "valid_password") + self.assertEqual(api.token, "f4k3") + self.assertEqual(api.token_refresh, "j5l4") + requests_post.reset_mock() + requests_post.return_value = MockResponse( + 200, create_mock_json("tests/resources/auth_refresh_token_success.json") + ) + api.refresh_token() + self.assertEqual(api.token, "newToken") + self.assertEqual(api.token_refresh, "newRefreshToken")