| 11 | |
| 12 | |
| 13 | class TestAuthenticationStateMachine: |
| 14 | password = b"router-password" |
| 15 | salt = b"01234567890123456789" |
| 16 | ok_packet = b"\0\0\0\2\0\0\0" |
| 17 | |
| 18 | @staticmethod |
| 19 | def packet(data): |
| 20 | return MysqlPacket(data, "utf8") |
| 21 | |
| 22 | def connection(self, **kwargs): |
| 23 | conn = pymysql.connect( |
| 24 | user="router-user", |
| 25 | password=self.password, |
| 26 | ssl_disabled=True, |
| 27 | defer_connect=True, |
| 28 | **kwargs, |
| 29 | ) |
| 30 | conn.server_version = "8.0.0" |
| 31 | conn.server_capabilities = CLIENT.PLUGIN_AUTH | CLIENT.SECURE_CONNECTION |
| 32 | conn.client_flag = CLIENT.PLUGIN_AUTH | CLIENT.SECURE_CONNECTION |
| 33 | conn.salt = self.salt |
| 34 | conn._auth_plugin_name = "caching_sha2_password" |
| 35 | conn._secure = True |
| 36 | return conn |
| 37 | |
| 38 | @pytest.mark.parametrize( |
| 39 | ("responses", "expected_auth_responses"), |
| 40 | [ |
| 41 | ([b"\x01\x04", ok_packet], [password + b"\0"]), |
| 42 | ( |
| 43 | [b"\xfemysql_native_password\0" + salt + b"\0", ok_packet], |
| 44 | [_auth.scramble_native_password(password, salt)], |
| 45 | ), |
| 46 | ( |
| 47 | [ |
| 48 | b"\x01\x04", |
| 49 | b"\xfemysql_native_password\0" + salt + b"\0", |
| 50 | ok_packet, |
| 51 | ], |
| 52 | [password + b"\0", _auth.scramble_native_password(password, salt)], |
| 53 | ), |
| 54 | ], |
| 55 | ids=["more-data", "auth-switch", "more-data-then-auth-switch"], |
| 56 | ) |
| 57 | def test_authentication_packet_transitions( |
| 58 | self, responses, expected_auth_responses |
| 59 | ): |
| 60 | """Exercise multi-step authentication without a MySQL server or Router.""" |
| 61 | conn = self.connection() |
| 62 | |
| 63 | packets = [self.packet(response) for response in responses] |
| 64 | with ( |
| 65 | mock.patch.object(conn, "write_packet") as write_packet, |
| 66 | mock.patch.object(conn, "_read_packet", side_effect=packets), |
| 67 | ): |
| 68 | conn._request_authentication() |
| 69 | |
| 70 | # The first write is the handshake response; subsequent writes are the |
nothing calls this directly
no outgoing calls
no test coverage detected