Skip to content

Commit 4ff50f6

Browse files
committed
PYTHON-940 Log warning when driver configures an authenticator, but server does not request authentication
1 parent 939212f commit 4ff50f6

4 files changed

Lines changed: 76 additions & 0 deletions

File tree

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Other
1111
* Reevaluate MONKEY_PATCH_LOOP in test codebase (PYTHON-903)
1212
* Remove CASS_SERVER_VERSION and replace it for CASSANDRA_VERSION in tests (PYTHON-910)
1313
* Refactor CASSANDRA_VERSION to a some kind of version object (PYTHON-915)
14+
* Log warning when driver configures an authenticator, but server does not request authentication (PYTHON-940)
1415

1516

1617
3.13.0

cassandra/connection.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,12 @@ def _handle_startup_response(self, startup_response, did_authenticate=False):
724724
if self.is_defunct:
725725
return
726726
if isinstance(startup_response, ReadyMessage):
727+
if self.authenticator:
728+
log.warning("An authentication challenge was not sent, "
729+
"this is suspicious because the driver expects "
730+
"authentication (configured authenticator = %s)",
731+
self.authenticator.__class__.__name__)
732+
727733
log.debug("Got ReadyMessage on new connection (%s) from %s", id(self), self.host)
728734
if self._compressor:
729735
self.compressor = self._compressor

tests/integration/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,22 @@ def get_message_count(self, level, sub_string):
619619
count+=1
620620
return count
621621

622+
def set_module_name(self, module_name):
623+
"""
624+
This is intended to be used doing:
625+
with MockLoggingHandler().set_module_name(connection.__name__) as mock_handler:
626+
"""
627+
self.module_name = module_name
628+
return self
629+
630+
def __enter__(self):
631+
self.logger = logging.getLogger(self.module_name)
632+
self.logger.addHandler(self)
633+
return self
634+
635+
def __exit__(self, *args):
636+
pass
637+
622638

623639
class BasicExistingKeyspaceUnitTestCase(BasicKeyspaceUnitTestCase):
624640
"""

tests/integration/standard/test_cluster.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636

3737
from cassandra.pool import Host
3838
from cassandra.query import SimpleStatement, TraceUnavailable, tuple_factory
39+
from cassandra.auth import PlainTextAuthProvider, SaslAuthProvider
40+
from cassandra import connection
3941

4042
from tests import notwindows
4143
from tests.integration import use_singledc, PROTOCOL_VERSION, get_server_versions, CASSANDRA_VERSION, \
@@ -672,6 +674,57 @@ def test_string_coverage(self):
672674
self.assertIn('result', str(future))
673675
cluster.shutdown()
674676

677+
def test_can_connect_with_plainauth(self):
678+
"""
679+
Verify that we can connect setting PlainTextAuthProvider against a
680+
C* server without authentication set. We also verify a warning is
681+
issued per connection. This test is here instead of in test_authentication.py
682+
because the C* server running in that module has auth set.
683+
684+
@since 3.14
685+
@jira_ticket PYTHON-940
686+
@expected_result we can connect, query C* and warning are issued
687+
688+
@test_category auth
689+
"""
690+
auth_provider = PlainTextAuthProvider(
691+
username="made_up_username",
692+
password="made_up_password"
693+
)
694+
self._warning_are_issued_when_auth(auth_provider)
695+
696+
def test_can_connect_with_sslauth(self):
697+
"""
698+
Verify that we can connect setting SaslAuthProvider against a
699+
C* server without authentication set. We also verify a warning is
700+
issued per connection. This test is here instead of in test_authentication.py
701+
because the C* server running in that module has auth set.
702+
703+
@since 3.14
704+
@jira_ticket PYTHON-940
705+
@expected_result we can connect, query C* and warning are issued
706+
707+
@test_category auth
708+
"""
709+
sasl_kwargs = {'service': 'cassandra',
710+
'mechanism': 'PLAIN',
711+
'qops': ['auth'],
712+
'username': "made_up_username",
713+
'password': "made_up_password"}
714+
715+
auth_provider = SaslAuthProvider(**sasl_kwargs)
716+
self._warning_are_issued_when_auth(auth_provider)
717+
718+
def _warning_are_issued_when_auth(self, auth_provider):
719+
with MockLoggingHandler().set_module_name(connection.__name__) as mock_handler:
720+
with Cluster(auth_provider=auth_provider) as cluster:
721+
session = cluster.connect()
722+
self.assertIsNotNone(session.execute("SELECT * from system.local"))
723+
724+
# Three conenctions to nodes plus the control connection
725+
self.assertEqual(4, mock_handler.get_message_count('warning',
726+
"An authentication challenge was not sent"))
727+
675728
def test_idle_heartbeat(self):
676729
interval = 2
677730
cluster = Cluster(protocol_version=PROTOCOL_VERSION, idle_heartbeat_interval=interval)

0 commit comments

Comments
 (0)