Commit 01801edd authored by zsoldosp's avatar zsoldosp Committed by Tim Graham
Browse files

Fixed #22646: Added support for the MySQL ssl-ca option to dbshell.

parent 69478859
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -695,6 +695,7 @@ answer newbie questions, and generally made Django that much better:
    Gasper Zejn <zejn@kiberpipa.org>
    Jarek Zgoda <jarek.zgoda@gmail.com>
    Cheng Zhang
    Peter Zsoldos <http://zsoldosp.eu>
    <Please alphabetize new entries>

A big THANK YOU goes to:
+9 −3
Original line number Diff line number Diff line
@@ -6,14 +6,15 @@ from django.db.backends import BaseDatabaseClient
class DatabaseClient(BaseDatabaseClient):
    executable_name = 'mysql'

    def runshell(self):
        settings_dict = self.connection.settings_dict
        args = [self.executable_name]
    @classmethod
    def settings_to_cmd_args(cls, settings_dict):
        args = [cls.executable_name]
        db = settings_dict['OPTIONS'].get('db', settings_dict['NAME'])
        user = settings_dict['OPTIONS'].get('user', settings_dict['USER'])
        passwd = settings_dict['OPTIONS'].get('passwd', settings_dict['PASSWORD'])
        host = settings_dict['OPTIONS'].get('host', settings_dict['HOST'])
        port = settings_dict['OPTIONS'].get('port', settings_dict['PORT'])
        cert = settings_dict['OPTIONS'].get('ssl', {}).get('ca')
        defaults_file = settings_dict['OPTIONS'].get('read_default_file')
        # Seems to be no good way to set sql_mode with CLI.

@@ -30,7 +31,12 @@ class DatabaseClient(BaseDatabaseClient):
                args += ["--host=%s" % host]
        if port:
            args += ["--port=%s" % port]
        if cert:
            args += ["--ssl-ca=%s" % cert]
        if db:
            args += [db]
        return args

    def runshell(self):
        args = DatabaseClient.settings_to_cmd_args(self.connection.settings_dict)
        subprocess.call(args)
+3 −0
Original line number Diff line number Diff line
@@ -203,6 +203,9 @@ Management Commands
  command is now always the ``dest`` name specified in the command option
  definition (as long as the command uses the new :py:mod:`argparse` module).

* The :djadmin:`dbshell` command now supports MySQL's optional SSL certificate
  authority setting (``--ssl-ca``).

Models
^^^^^^

+0 −0

Empty file added.

tests/dbshell/tests.py

0 → 100644
+73 −0
Original line number Diff line number Diff line
from django.db.backends.mysql.client import DatabaseClient
from django.test import SimpleTestCase


class MySqlDbshellCommandTestCase(SimpleTestCase):

    def test_fails_with_keyerror_on_incomplete_config(self):
        with self.assertRaises(KeyError):
            self.get_command_line_arguments({})

    def test_basic_params_specified_in_settings(self):
        self.assertEqual(
            ['mysql', '--user=someuser', '--password=somepassword',
             '--host=somehost', '--port=444', 'somedbname'],
            self.get_command_line_arguments({
                'NAME': 'somedbname',
                'USER': 'someuser',
                'PASSWORD': 'somepassword',
                'HOST': 'somehost',
                'PORT': 444,
                'OPTIONS': {},
            }))

    def test_options_override_settings_proper_values(self):
        settings_port = 444
        options_port = 555
        self.assertNotEqual(settings_port, options_port, 'test pre-req')
        self.assertEqual(
            ['mysql', '--user=optionuser', '--password=optionpassword',
             '--host=optionhost', '--port={}'.format(options_port), 'optiondbname'],
            self.get_command_line_arguments({
                'NAME': 'settingdbname',
                'USER': 'settinguser',
                'PASSWORD': 'settingpassword',
                'HOST': 'settinghost',
                'PORT': settings_port,
                'OPTIONS': {
                    'db': 'optiondbname',
                    'user': 'optionuser',
                    'passwd': 'optionpassword',
                    'host': 'optionhost',
                    'port': options_port,
                },
            }))

    def test_can_connect_using_sockets(self):
        self.assertEqual(
            ['mysql', '--user=someuser', '--password=somepassword',
             '--socket=/path/to/mysql.socket.file', 'somedbname'],
            self.get_command_line_arguments({
                'NAME': 'somedbname',
                'USER': 'someuser',
                'PASSWORD': 'somepassword',
                'HOST': '/path/to/mysql.socket.file',
                'PORT': None,
                'OPTIONS': {},
            }))

    def test_ssl_certificate_is_added(self):
        self.assertEqual(
            ['mysql', '--user=someuser', '--password=somepassword',
             '--host=somehost', '--port=444', '--ssl-ca=sslca', 'somedbname'],
            self.get_command_line_arguments({
                'NAME': 'somedbname',
                'USER': 'someuser',
                'PASSWORD': 'somepassword',
                'HOST': 'somehost',
                'PORT': 444,
                'OPTIONS': {'ssl': {'ca': 'sslca'}},
            }))

    def get_command_line_arguments(self, connection_settings):
        return DatabaseClient.settings_to_cmd_args(connection_settings)