From a6d3dd8e227cbaf0b727d4e97ca6f6eda06970ef Mon Sep 17 00:00:00 2001 From: amcrn Date: Mon, 28 Oct 2013 16:50:47 -0700 Subject: [PATCH] User-Create Host Does Not Allow Wildcarded Octet as of now, the only wildcarding pattern that will succeed for user-create's 'host' parameter is '%'. this patch permits wildcarded octets, e.g. '10.%' & '192.168.1.%' Change-Id: If58ee69381d1bbf3be4af37c045d6f8a2d924947 Closes-Bug: 1245705 --- trove/guestagent/db/models.py | 2 +- .../unittests/guestagent/test_dbmodels.py | 26 ++++++++++- .../unittests/mysql/test_user_controller.py | 46 +++++++++++++++++-- 3 files changed, 69 insertions(+), 5 deletions(-) diff --git a/trove/guestagent/db/models.py b/trove/guestagent/db/models.py index 1bd41abe40..766b53fbd2 100644 --- a/trove/guestagent/db/models.py +++ b/trove/guestagent/db/models.py @@ -389,7 +389,7 @@ class MySQLUser(Base): # A, A.B, A.B.C, and A.B.C.D are all valid technically. return False try: - octets = [int(octet, 10) for octet in octets] + octets = [int(octet, 10) for octet in octets if octet != '%'] except ValueError: # If these weren't decimal, there's a problem. return False diff --git a/trove/tests/unittests/guestagent/test_dbmodels.py b/trove/tests/unittests/guestagent/test_dbmodels.py index 826e3866b1..953c948f1a 100644 --- a/trove/tests/unittests/guestagent/test_dbmodels.py +++ b/trove/tests/unittests/guestagent/test_dbmodels.py @@ -30,7 +30,7 @@ class MySQLDatabaseTest(testtools.TestCase): self.mysqlDb._ignore_dbs = self.origin_ignore_db def test_name(self): - self.assertIsNone(self.mysqlDb.name) + self.assertEqual(self.mysqlDb.name, None) def test_name_setter(self): test_name = "Anna" @@ -84,3 +84,27 @@ class IsValidUsernameTest(testtools.TestCase): self.mysqlUser._is_valid = MagicMock(return_value=True) self.assertFalse(self.mysqlUser._is_valid_user_name("king")) + + +class IsValidHostnameTest(testtools.TestCase): + def setUp(self): + super(IsValidHostnameTest, self).setUp() + self.mysqlUser = dbmodels.MySQLUser() + + def tearDown(self): + super(IsValidHostnameTest, self).tearDown() + + def test_is_valid_octet(self): + self.assertTrue(self.mysqlUser._is_valid_host_name('192.168.1.1')) + + def test_is_valid_bad_octet(self): + self.assertFalse(self.mysqlUser._is_valid_host_name('999.168.1.1')) + + def test_is_valid_global_wildcard(self): + self.assertTrue(self.mysqlUser._is_valid_host_name('%')) + + def test_is_valid_prefix_wildcard(self): + self.assertTrue(self.mysqlUser._is_valid_host_name('%.168.1.1')) + + def test_is_valid_suffix_wildcard(self): + self.assertTrue(self.mysqlUser._is_valid_host_name('192.168.1.%')) diff --git a/trove/tests/unittests/mysql/test_user_controller.py b/trove/tests/unittests/mysql/test_user_controller.py index 876c859c4c..ee882a378c 100644 --- a/trove/tests/unittests/mysql/test_user_controller.py +++ b/trove/tests/unittests/mysql/test_user_controller.py @@ -124,6 +124,46 @@ class TestUserController(TestCase): validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) + def test_validate_create_host_no_wildcard(self): + body = {"users": [{"databases": [{"name": "x"}], "name": "joe", + "password": "123", "host": "192.168.1.1"}]} + schema = self.controller.get_schema('create', body) + validator = jsonschema.Draft4Validator(schema) + self.assertTrue(validator.is_valid(body)) + + def test_validate_create_host_wildcard(self): + body = {"users": [{"databases": [{"name": "x"}], "name": "joe", + "password": "123", "host": "%"}]} + schema = self.controller.get_schema('create', body) + validator = jsonschema.Draft4Validator(schema) + self.assertTrue(validator.is_valid(body)) + + def test_validate_create_host_wildcard_prefix(self): + body = {"users": [{"databases": [{"name": "x"}], "name": "joe", + "password": "123", "host": "%.168.1.1"}]} + schema = self.controller.get_schema('create', body) + validator = jsonschema.Draft4Validator(schema) + self.assertTrue(validator.is_valid(body)) + + def test_validate_create_host_wildcard_middle(self): + body = {"users": [{"databases": [{"name": "x"}], "name": "joe", + "password": "123", "host": "192.%.1.1"}]} + schema = self.controller.get_schema('create', body) + validator = jsonschema.Draft4Validator(schema) + self.assertFalse(validator.is_valid(body)) + errors = sorted(validator.iter_errors(body), key=lambda e: e.path) + self.assertThat(len(errors), Is(1)) + self.assertThat(errors[0].message, + Equals(("'192.%.1.1' does not match " + "'^[%]?[\\\\w(-).]*[%]?$'"))) + + def test_validate_create_host_wildcard_suffix(self): + body = {"users": [{"databases": [{"name": "x"}], "name": "joe", + "password": "123", "host": "192.168.1.%"}]} + schema = self.controller.get_schema('create', body) + validator = jsonschema.Draft4Validator(schema) + self.assertTrue(validator.is_valid(body)) + def test_validate_update_empty(self): body = {"users": []} schema = self.controller.get_schema('update_all', body) @@ -292,7 +332,7 @@ class TestSchemaController(TestCase): def test_validate_mixed(self): schema = self.controller.get_schema('create', self.body) - self.assertIsNotNone(schema) + self.assertNotEqual(schema, None) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(self.body)) @@ -300,14 +340,14 @@ class TestSchemaController(TestCase): body = self.body.copy() body['databases'].append({"collate": "some_collation"}) schema = self.controller.get_schema('create', body) - self.assertIsNotNone(schema) + self.assertNotEqual(schema, None) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) def test_validate_empty(self): body = {"databases": []} schema = self.controller.get_schema('create', body) - self.assertIsNotNone(schema) + self.assertNotEqual(schema, None) self.assertTrue('databases' in body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body))