Skip to content

Commit

Permalink
Merge pull request #2031 from yandrieiev/fail_fast_when_invalid_db_name
Browse files Browse the repository at this point in the history
Fail fast when db name is invalid
  • Loading branch information
bagerard committed Apr 10, 2019
2 parents 9bb3dfd + b521309 commit c439150
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 1 deletion.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,4 @@ that much better:
* Gleb Voropaev (https://github.com/buggyspace)
* Paulo Amaral (https://github.com/pauloAmaral)
* Gaurav Dadhania (https://github.com/GVRV)
* Yurii Andrieiev (https://github.com/yandrieiev)
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Development
- POTENTIAL BREAKING CHANGE: Aggregate gives wrong results when used with a queryset having limit and skip #2029
- mongoengine now requires pymongo>=3.5 #2017
- Generate Unique Indices for SortedListField and EmbeddedDocumentListFields #2020
- connect() fails immediately when db name contains invalid characters (e. g. when user mistakenly puts 'mongodb://127.0.0.1:27017' as db name, happened in #1718) or is if db name is of an invalid type
- (Fill this out as you fix issues and develop your features).

Changes in 0.17.0
Expand Down
12 changes: 12 additions & 0 deletions mongoengine/connection.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from pymongo import MongoClient, ReadPreference, uri_parser
from pymongo.database import _check_name
import six

from mongoengine.pymongo_support import IS_PYMONGO_3
Expand Down Expand Up @@ -28,6 +29,16 @@ class MongoEngineConnectionError(Exception):
_dbs = {}


def check_db_name(name):
"""Check if a database name is valid.
This functionality is copied from pymongo Database class constructor.
"""
if not isinstance(name, six.string_types):
raise TypeError('name must be an instance of %s' % six.string_types)
elif name != '$external':
_check_name(name)


def register_connection(alias, db=None, name=None, host=None, port=None,
read_preference=READ_PREFERENCE,
username=None, password=None,
Expand Down Expand Up @@ -69,6 +80,7 @@ def register_connection(alias, db=None, name=None, host=None, port=None,
'authentication_mechanism': authentication_mechanism
}

check_db_name(conn_settings['name'])
conn_host = conn_settings['host']

# Host can be a list or a string, so if string, force to a list.
Expand Down
32 changes: 31 additions & 1 deletion tests/test_connection.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import datetime
from pymongo.errors import OperationFailure
from pymongo.errors import OperationFailure, InvalidName

try:
import unittest2 as unittest
Expand Down Expand Up @@ -49,6 +49,36 @@ def test_connect(self):
conn = get_connection('testdb')
self.assertIsInstance(conn, pymongo.mongo_client.MongoClient)

def test_connect_with_invalid_db_name(self):
"""Ensure that connect() method fails fast if db name is invalid
"""
with self.assertRaises(InvalidName):
connect('mongomock://localhost')

def test_connect_with_db_name_external(self):
"""Ensure that connect() works if db name is $external
"""
"""Ensure that the connect() method works properly."""
connect('$external')

conn = get_connection()
self.assertIsInstance(conn, pymongo.mongo_client.MongoClient)

db = get_db()
self.assertIsInstance(db, pymongo.database.Database)
self.assertEqual(db.name, '$external')

connect('$external', alias='testdb')
conn = get_connection('testdb')
self.assertIsInstance(conn, pymongo.mongo_client.MongoClient)

def test_connect_with_invalid_db_name_type(self):
"""Ensure that connect() method fails fast if db name has invalid type
"""
with self.assertRaises(TypeError):
non_string_db_name = ['e. g. list instead of a string']
connect(non_string_db_name)

def test_connect_in_mocking(self):
"""Ensure that the connect() method works properly in mocking.
"""
Expand Down

0 comments on commit c439150

Please sign in to comment.