Skip to content

Commit a3668f1

Browse files
committed
Merge pull request pandas-dev#32 from manahl/bugfix/MDP-341-authorization-error-seen-in-prod-2
MDP-341 Reauthing as admin if connection is not authenticated when the library binding is created
2 parents 17343e6 + d2d93b2 commit a3668f1

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

arctic/arctic.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,14 @@ def __init__(self, arctic, library):
333333
self.database_name = database_name
334334
self._db = self.arctic._conn[database_name]
335335
self._auth(self._db)
336+
337+
auth_users = self._db.command({'connectionStatus': 1})['authInfo']['authenticatedUsers']
338+
if all((r['userSource'] != self._db.name for r in auth_users)):
339+
# We're not authenticated to the database,
340+
# ensure we are authed to admin so that we can at least read from it
341+
if all((r['userSource'] != 'admin' for r in auth_users)):
342+
self._auth(self.arctic._adminDB)
343+
336344
self._library_coll = self._db[library]
337345

338346
def __str__(self):
@@ -356,7 +364,7 @@ def _auth(self, database):
356364

357365
auth = get_auth(self.arctic.mongo_host, self.arctic._application_name, database.name)
358366
if auth:
359-
authenticate(self._db, auth.user, auth.password)
367+
authenticate(database, auth.user, auth.password)
360368
self.arctic._conn.close()
361369

362370
def get_name(self):

tests/unit/test_arctic.py

+34
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,14 @@ def test_arctic_lazy_init():
2020
# do something to trigger lazy arctic init
2121
store.list_libraries()
2222
assert mc.called
23+
24+
mock_conn_info = {u'authInfo':
25+
{u'authenticatedUsers': [{u'user': u'research', u'userSource': u'admin'}]},
26+
u'ok': 1.0}
2327

28+
mock_conn_info_empty = {u'authInfo':
29+
{u'authenticatedUsers': []},
30+
u'ok': 1.0}
2431

2532
def test_arctic_auth():
2633
with patch('pymongo.MongoClient', return_value=MagicMock(), autospec=True), \
@@ -39,6 +46,7 @@ def test_arctic_auth():
3946
with patch('arctic.arctic.ArcticLibraryBinding.get_library_type', return_value=None, autospec=True):
4047
ga.return_value = Credential('db', 'user', 'pass')
4148
store._conn['arctic_jblackburn'].name = 'arctic_jblackburn'
49+
store._conn['arctic_jblackburn'].command.return_value = mock_conn_info
4250
store['jblackburn.library']
4351

4452
# Creating the library will have attempted to auth against it
@@ -62,12 +70,38 @@ def test_arctic_auth_custom_app_name():
6270
with patch('arctic.arctic.ArcticLibraryBinding.get_library_type', return_value=None, autospec=True):
6371
ga.return_value = Credential('db', 'user', 'pass')
6472
store._conn['arctic_jblackburn'].name = 'arctic_jblackburn'
73+
store._conn['arctic_jblackburn'].command.return_value = mock_conn_info
6574
store['jblackburn.library']
6675

6776
# Creating the library will have attempted to auth against it
6877
assert ga.call_args_list == [call('cluster', sentinel.app_name, 'arctic_jblackburn')]
6978

7079

80+
def test_arctic_auth_admin_reauth():
81+
with patch('pymongo.MongoClient', return_value=MagicMock(), autospec=True), \
82+
patch('arctic.arctic.mongo_retry', autospec=True), \
83+
patch('arctic.arctic.get_auth', autospec=True) as ga:
84+
ga.return_value = Credential('db', 'admin_user', 'admin_pass')
85+
store = Arctic('cluster')
86+
# do something to trigger lazy arctic init
87+
store.list_libraries()
88+
assert ga.call_args_list == [call('cluster', 'arctic', 'admin')]
89+
ga.reset_mock()
90+
91+
# Get a 'missing' library
92+
with pytest.raises(LibraryNotFoundException):
93+
with patch('arctic.arctic.ArcticLibraryBinding.get_library_type', return_value=None, autospec=True), \
94+
patch('arctic.arctic.logger') as logger:
95+
ga.return_value = Credential('db', 'user', 'pass')
96+
store._conn['arctic_jblackburn'].name = 'arctic_jblackburn'
97+
store._conn['arctic_jblackburn'].command.return_value = mock_conn_info_empty
98+
store['jblackburn.library']
99+
100+
assert store._conn['arctic_jblackburn'].command.call_args_list == [call({'connectionStatus': 1})]
101+
assert ga.call_args_list == [call('cluster', 'arctic', 'arctic_jblackburn'),
102+
call('cluster', 'arctic', store._adminDB.name)]
103+
104+
71105
def test_arctic_connect_hostname():
72106
with patch('pymongo.MongoClient', return_value=MagicMock(), autospec=True) as mc, \
73107
patch('arctic.arctic.mongo_retry', autospec=True) as ar, \

0 commit comments

Comments
 (0)