|
17 | 17 |
|
18 | 18 | from unittest import mock |
19 | 19 |
|
| 20 | +import requests |
20 | 21 | import responses |
| 22 | +from requests import Request |
21 | 23 | from requests.auth import AuthBase |
22 | 24 |
|
23 | 25 | from eodag.api.provider import ProvidersDict |
| 26 | +from eodag.plugins.authentication.eoiam import EOIAMSessionAuth |
24 | 27 | from eodag.plugins.manager import PluginManager |
25 | 28 | from eodag.utils.exceptions import AuthenticationError, MisconfiguredError |
26 | 29 | from tests.units.auth_plugins.base import BaseAuthPluginTest |
@@ -107,9 +110,9 @@ def test_plugins_auth_eoiam_authenticate_no_login_required(self): |
107 | 110 | auth = auth_plugin.authenticate() |
108 | 111 | req = mock.Mock(headers={}) |
109 | 112 | req.url = "http://test.url" |
110 | | - auth(req) |
111 | | - |
112 | | - self.assertFalse(auth_plugin._logged_in is False) |
| 113 | + with mock.patch.object(auth_plugin, "_login_from_html") as mock_login_from_html: |
| 114 | + auth(req) |
| 115 | + mock_login_from_html.assert_not_called() |
113 | 116 |
|
114 | 117 | @responses.activate |
115 | 118 | def test_plugins_auth_eoiam_login_from_html_success(self): |
@@ -556,3 +559,74 @@ def test_plugins_auth_eoiam_data_access_required(self): |
556 | 559 | AuthenticationError, f"Data access request required: .* {final_url}" |
557 | 560 | ): |
558 | 561 | auth_plugin._login_from_html(login_html, req_url="http://test.url") |
| 562 | + |
| 563 | + def test_eoiam_session_auth_call_triggers_login_and_prepares_cookies(self): |
| 564 | + """_EOIAMSessionAuth.__call__ should trigger login when landing on EOIAM page""" |
| 565 | + auth_plugin = self.get_auth_plugin("foo_provider") |
| 566 | + auth_plugin.config.credentials = { |
| 567 | + "username": "test_user", |
| 568 | + "password": "test_pass", |
| 569 | + } |
| 570 | + |
| 571 | + # prepare a requests PreparedRequest |
| 572 | + req = Request("GET", "http://service.test/resource").prepare() |
| 573 | + |
| 574 | + # initial session.get returns EOIAM page |
| 575 | + initial_resp = requests.Response() |
| 576 | + initial_resp._content = ( |
| 577 | + b"Earth Observation Identity and Access Management System" |
| 578 | + ) |
| 579 | + initial_resp.url = "http://login" |
| 580 | + |
| 581 | + # login result is a normal response |
| 582 | + login_result = requests.Response() |
| 583 | + login_result._content = b"{}" |
| 584 | + |
| 585 | + old_session = auth_plugin.session |
| 586 | + |
| 587 | + with mock.patch.object(auth_plugin.session, "get", return_value=initial_resp): |
| 588 | + with mock.patch.object( |
| 589 | + auth_plugin, "_login_from_html", return_value=login_result |
| 590 | + ) as mock_login: |
| 591 | + # ensure there is a cookie jar so prepare_cookies can operate |
| 592 | + jar = requests.cookies.RequestsCookieJar() |
| 593 | + jar.set("sid", "1234", domain="service.test", path="/") |
| 594 | + auth_plugin.session.cookies = jar |
| 595 | + |
| 596 | + auth = EOIAMSessionAuth(auth_plugin) |
| 597 | + returned = auth(req) |
| 598 | + |
| 599 | + mock_login.assert_called_once_with(initial_resp.text, req.url) |
| 600 | + self.assertIs(returned, req) |
| 601 | + |
| 602 | + self.assertIsInstance(auth_plugin.session, requests.Session) |
| 603 | + self.assertIsNot(auth_plugin.session, old_session) |
| 604 | + |
| 605 | + def test_eoiam_session_auth_call_resets_session_on_login_error(self): |
| 606 | + """_EOIAMSessionAuth.__call__ should reset session even when login fails""" |
| 607 | + auth_plugin = self.get_auth_plugin("foo_provider") |
| 608 | + auth_plugin.config.credentials = { |
| 609 | + "username": "test_user", |
| 610 | + "password": "test_pass", |
| 611 | + } |
| 612 | + |
| 613 | + req = Request("GET", "http://service.test/resource").prepare() |
| 614 | + initial_resp = requests.Response() |
| 615 | + initial_resp._content = ( |
| 616 | + b"Earth Observation Identity and Access Management System" |
| 617 | + ) |
| 618 | + initial_resp.url = "http://login" |
| 619 | + |
| 620 | + old_session = auth_plugin.session |
| 621 | + with mock.patch.object(auth_plugin.session, "get", return_value=initial_resp): |
| 622 | + with mock.patch.object( |
| 623 | + auth_plugin, |
| 624 | + "_login_from_html", |
| 625 | + side_effect=AuthenticationError("boom"), |
| 626 | + ): |
| 627 | + auth = EOIAMSessionAuth(auth_plugin) |
| 628 | + with self.assertRaises(AuthenticationError): |
| 629 | + auth(req) |
| 630 | + |
| 631 | + self.assertIsInstance(auth_plugin.session, requests.Session) |
| 632 | + self.assertIsNot(auth_plugin.session, old_session) |
0 commit comments