Repository: CS-SI/eodag
Pull request #555 (2022-11-21 16:31:44)

fix: warning if keycloak auth error while discovering product types
- Fixes some keycloak auth errors catching
- Log a warning instead of raising an exception if auth fails when discovering product types

github-actions[bot]: ## Unit Test Results
    2 files  ±0      2 suites  ±0   9m 11s [:stopwatch:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "duration of all tests") - 1m 16s
319 tests ±0  316 [:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "passed tests") ±0  3 [:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "skipped / disabled tests") ±0  0 [:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "failed tests") ±0 
638 runs  ±0  632 [:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "passed tests") ±0  6 [:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "skipped / disabled tests") ±0  0 [:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "failed tests") ±0 

Results for commit 7b6359f7. ± Comparison against base commit 2ddca493.

[test-results]:data:application/gzip;base64,H4sIAMmpe2MC/03MSw6DIBSF4a0Yxh0g13uBbqZRCgmpjwZhZLr3ohXq8P9Ocjbm/GhXdm/ErWFr8rHGM4U++mXOidhmyFPcR2h1qceajDmI/vTy750quN6PGXgFG8ISTglp3j8J1BnlkkBU+T1S6cvh0dc/s0yTjzmYHAhQO6kGVHxA3mohOlAShQRBznakUekO2OcL6YSK/gUBAAA=

github-actions[bot]: <strong> </strong>

| File | Coverage |   |
| - | :-: | :-: |
| **All files** | `85%` | :white_check_mark: |
| eodag/api/core.py | `92%` | :white_check_mark: |
| eodag/plugins/authentication/keycloak.py | `52%` | :x: |

<strong> </strong>

| File | Coverage |   |
| - | :-: | :-: |
| **All files** | `84%` | :white_check_mark: |
| eodag/api/core.py | `92%` | :white_check_mark: |
| eodag/plugins/authentication/keycloak.py | `52%` | :x: |
| eodag/api/core.py | `92%` | :white_check_mark: |
| eodag/plugins/authentication/keycloak.py | `52%` | :x: |

_Minimum allowed coverage is `70%`_

<p align="right">Generated by :monkey: cobertura-action against 7b6359f78b580b5019224387527326fe46958943 </p>

Patch:
diff --git a/eodag/api/core.py b/eodag/api/core.py
index ac9f28d8..037f77b7 100644
--- a/eodag/api/core.py
+++ b/eodag/api/core.py
@@ -56,6 +56,7 @@ from eodag.utils import (
 )
 from eodag.utils.exceptions import (
     AuthenticationError,
+    MisconfiguredError,
     NoMatchingProductType,
     PluginImplementationError,
     UnsupportedProvider,
@@ -648,11 +649,20 @@ class EODataAccessGateway(object):
                         search_plugin.provider
                     )
                     if callable(getattr(auth_plugin, "authenticate", None)):
-                        search_plugin.auth = auth_plugin.authenticate()
+                        try:
+                            search_plugin.auth = auth_plugin.authenticate()
+                        except (AuthenticationError, MisconfiguredError) as e:
+                            logger.warning(
+                                f"Could not authenticate on {provider}: {str(e)}"
+                            )
+                            ext_product_types_conf[provider] = None
+                            continue
                     else:
-                        raise AuthenticationError(
-                            f"Could not authenticate using {auth_plugin} plugin"
+                        logger.warning(
+                            f"Could not authenticate on {provider} using {auth_plugin} plugin"
                         )
+                        ext_product_types_conf[provider] = None
+                        continue
 
                 ext_product_types_conf[
                     provider
diff --git a/eodag/plugins/authentication/keycloak.py b/eodag/plugins/authentication/keycloak.py
index 6b3e774d..f1418c04 100644
--- a/eodag/plugins/authentication/keycloak.py
+++ b/eodag/plugins/authentication/keycloak.py
@@ -39,21 +39,21 @@ class KeycloakOIDCPasswordAuth(Authentication):
         Makes authentication request
         """
         self.validate_config_credentials()
-        response = self.session.post(
-            self.TOKEN_URL_TEMPLATE.format(
-                auth_base_uri=self.config.auth_base_uri.rstrip("/"),
-                realm=self.config.realm,
-            ),
-            data={
-                "client_id": self.config.client_id,
-                "client_secret": self.config.client_secret,
-                "username": self.config.credentials["username"],
-                "password": self.config.credentials["password"],
-                "grant_type": self.GRANT_TYPE,
-            },
-            timeout=HTTP_REQ_TIMEOUT,
-        )
         try:
+            response = self.session.post(
+                self.TOKEN_URL_TEMPLATE.format(
+                    auth_base_uri=self.config.auth_base_uri.rstrip("/"),
+                    realm=self.config.realm,
+                ),
+                data={
+                    "client_id": self.config.client_id,
+                    "client_secret": self.config.client_secret,
+                    "username": self.config.credentials["username"],
+                    "password": self.config.credentials["password"],
+                    "grant_type": self.GRANT_TYPE,
+                },
+                timeout=HTTP_REQ_TIMEOUT,
+            )
             response.raise_for_status()
         except requests.RequestException as e:
             # check if error is identified as auth_error in provider conf


Test patch:
diff --git a/tests/integration/test_core_config.py b/tests/integration/test_core_config.py
index 4b7bfe1f..178dafd1 100644
--- a/tests/integration/test_core_config.py
+++ b/tests/integration/test_core_config.py
@@ -24,7 +24,6 @@ from tests.context import (
     AuthenticationError,
     EODataAccessGateway,
     HeaderAuth,
-    MisconfiguredError,
     PluginConfig,
 )
 
@@ -151,11 +150,15 @@ class TestCoreProductTypesConfig(TestCase):
                         productType: '{productType}'
             """
         )
-        self.assertRaises(
-            AuthenticationError,
-            self.dag.discover_product_types,
-            provider="foo_provider",
-        )
+        with self.assertLogs(level="WARNING") as cm:
+            ext_product_types_conf = self.dag.discover_product_types(
+                provider="foo_provider"
+            )
+            self.assertIsNone(ext_product_types_conf["foo_provider"])
+            self.assertIn(
+                "Could not authenticate on foo_provider using None plugin",
+                str(cm.output),
+            )
 
         # with auth plugin but without credentials
         self.dag.update_providers_config(
@@ -167,12 +170,17 @@ class TestCoreProductTypesConfig(TestCase):
                         Authorization: "Apikey {apikey}"
             """
         )
-        with self.assertRaisesRegex(
-            MisconfiguredError, r"Missing credentials configuration .*"
-        ):
-            self.dag.discover_product_types(provider="foo_provider")
-
-        # with auth plugin and credentials
+        with self.assertLogs(level="WARNING") as cm:
+            ext_product_types_conf = self.dag.discover_product_types(
+                provider="foo_provider"
+            )
+            self.assertIsNone(ext_product_types_conf["foo_provider"])
+            self.assertIn(
+                "Could not authenticate on foo_provider: Missing credentials",
+                str(cm.output),
+            )
+
+        # succeeds with auth plugin and credentials
         self.dag.update_providers_config(
             """
             foo_provider:
@@ -192,3 +200,20 @@ class TestCoreProductTypesConfig(TestCase):
         )
         call_args, call_kwargs = mock_requests_get.call_args
         self.assertIsInstance(call_kwargs["auth"], HeaderAuth)
+
+        # warning if another AuthenticationError
+        with mock.patch(
+            "eodag.plugins.manager.PluginManager.get_auth_plugin",
+        ) as mock_get_auth_plugin:
+            mock_get_auth_plugin.return_value.authenticate.side_effect = (
+                AuthenticationError("cannot auth for test")
+            )
+            with self.assertLogs(level="WARNING") as cm:
+                ext_product_types_conf = self.dag.discover_product_types(
+                    provider="foo_provider"
+                )
+                self.assertIsNone(ext_product_types_conf["foo_provider"])
+                self.assertIn(
+                    "Could not authenticate on foo_provider: cannot auth for test",
+                    str(cm.output),
+                )