def testServerRootSetting(self): settingModel = Setting() with self.assertRaises(ValidationException): settingModel.set(SettingKey.SERVER_ROOT, 'bad_value') settingModel.set(SettingKey.SERVER_ROOT, 'https://somedomain.org/foo') self.assertEqual(getApiUrl(), 'https://somedomain.org/foo/api/v1')
def testSettingsCache(db, enabledCache): setting = Setting() # 'foo' should be cached as the brand name setting.set(SettingKey.BRAND_NAME, 'foo') # change the brand name bypassing the cache via mongo returnedSetting = setting.findOne({'key': SettingKey.BRAND_NAME}) returnedSetting['value'] = 'bar' # verify the cache still gives us the old brand name assert setting.get(SettingKey.BRAND_NAME) == 'foo' # change the brand name through .set (which updates the cache) setting.set(SettingKey.BRAND_NAME, 'bar') # verify retrieving gives us the new value with mock.patch.object(setting, 'findOne') as findOneMock: assert setting.get(SettingKey.BRAND_NAME) == 'bar' # findOne shouldn't be called since the cache is returning the setting findOneMock.assert_not_called() # unset the setting, invalidating the cache setting.unset(SettingKey.BRAND_NAME) # verify the database needs to be accessed to retrieve the setting now with mock.patch.object(setting, 'findOne') as findOneMock: setting.get(SettingKey.BRAND_NAME) findOneMock.assert_called_once()
def testSettingsCache(db, enabledCache): setting = Setting() # 'foo' should be cached as the brand name setting.set(SettingKey.BRAND_NAME, 'foo') # change the brand name bypassing the cache via mongo returnedSetting = setting.findOne({'key': SettingKey.BRAND_NAME}) returnedSetting['value'] = 'bar' # verify the cache still gives us the old brand name assert setting.get(SettingKey.BRAND_NAME) == 'foo' # change the brand name through .set (which updates the cache) setting.set(SettingKey.BRAND_NAME, 'bar') # verify retrieving gives us the new value with unittest.mock.patch.object(setting, 'findOne') as findOneMock: assert setting.get(SettingKey.BRAND_NAME) == 'bar' # findOne shouldn't be called since the cache is returning the setting findOneMock.assert_not_called() # unset the setting, invalidating the cache setting.unset(SettingKey.BRAND_NAME) # verify the database needs to be accessed to retrieve the setting now with unittest.mock.patch.object(setting, 'findOne') as findOneMock: setting.get(SettingKey.BRAND_NAME) findOneMock.assert_called_once()
def _maybeConvertSettings(self, endpointIds, endpointNames): # remove me if isinstance(endpointIds, str): endpointIds = {None: endpointIds} endpointNames = {None: endpointNames} settings = Setting() settings.set(PluginSettings.GLOBUS_ENDPOINT_ID, endpointIds) settings.set(PluginSettings.GLOBUS_ENDPOINT_NAME, endpointNames) return (endpointIds, endpointNames)
def _storeEndpointData(self, key, endpointId, endpointName): settings = Setting() endpointIds = settings.get(PluginSettings.GLOBUS_ENDPOINT_ID, None) endpointNames = settings.get(PluginSettings.GLOBUS_ENDPOINT_NAME, None) if endpointIds is None: endpointIds = {} endpointNames = {} endpointIds[key] = endpointId endpointNames[key] = endpointName settings.set(PluginSettings.GLOBUS_ENDPOINT_ID, endpointIds) settings.set(PluginSettings.GLOBUS_ENDPOINT_NAME, endpointNames)
def testValidators(self): settingModel = Setting() @setting_utilities.validator('test.key1') def key1v1(doc): raise ValidationException('key1v1') with six.assertRaisesRegex(self, ValidationException, '^key1v1$'): settingModel.set('test.key1', '') @setting_utilities.validator('test.key1') def key1v2(doc): raise ValidationException('key1v2') with six.assertRaisesRegex(self, ValidationException, '^key1v2$'): settingModel.set('test.key1', '') @setting_utilities.validator('test.key2') def key2v1(doc): raise ValidationException('key2v1') with six.assertRaisesRegex(self, ValidationException, '^key2v1$'): settingModel.set('test.key2', '') @setting_utilities.validator('test.key2', replace=True) def key2v2(doc): doc['value'] = 'modified' setting = settingModel.set('test.key2', 'original') self.assertEqual(setting['value'], 'modified')
def testValidators(self): settingModel = Setting() @setting_utilities.validator('test.key1') def key1v1(doc): raise ValidationException('key1v1') with self.assertRaisesRegex(ValidationException, '^key1v1$'): settingModel.set('test.key1', '') @setting_utilities.validator('test.key1') def key1v2(doc): raise ValidationException('key1v2') with self.assertRaisesRegex(ValidationException, '^key1v2$'): settingModel.set('test.key1', '') @setting_utilities.validator('test.key2') def key2v1(doc): raise ValidationException('key2v1') with self.assertRaisesRegex(ValidationException, '^key2v1$'): settingModel.set('test.key2', '') @setting_utilities.validator('test.key2', replace=True) def key2v2(doc): doc['value'] = 'modified' setting = settingModel.set('test.key2', 'original') self.assertEqual(setting['value'], 'modified')
def enablePlugins(self, plugins): # Determine what plugins have been disabled and remove their associated routes. setting = Setting() routeTable = setting.get(SettingKey.ROUTE_TABLE) oldPlugins = setting.get(SettingKey.PLUGINS_ENABLED) reservedRoutes = {GIRDER_ROUTE_ID, GIRDER_STATIC_ROUTE_ID} routeTableChanged = False removedRoutes = (set(oldPlugins) - set(plugins) - reservedRoutes) for route in removedRoutes: if route in routeTable: del routeTable[route] routeTableChanged = True if routeTableChanged: setting.set(SettingKey.ROUTE_TABLE, routeTable) # Route cleanup is done; update list of enabled plugins. return setting.set(SettingKey.PLUGINS_ENABLED, plugins)
def enablePlugins(self, plugins): # Determine what plugins have been disabled and remove their associated routes. setting = Setting() routeTable = setting.get(SettingKey.ROUTE_TABLE) oldPlugins = setting.get(SettingKey.PLUGINS_ENABLED) reservedRoutes = {GIRDER_ROUTE_ID, GIRDER_STATIC_ROUTE_ID} routeTableChanged = False removedRoutes = ( set(oldPlugins) - set(plugins) - reservedRoutes) for route in removedRoutes: if route in routeTable: del routeTable[route] routeTableChanged = True if routeTableChanged: setting.set(SettingKey.ROUTE_TABLE, routeTable) # Route cleanup is done; update list of enabled plugins. return setting.set(SettingKey.PLUGINS_ENABLED, plugins)
def setUp(self, assetstoreType=None, dropModels=True): """ We want to start with a clean database each time, so we drop the test database before each test. We then add an assetstore so the file model can be used without 500 errors. :param assetstoreType: if 'gridfs' or 's3', use that assetstore. 'gridfsrs' uses a GridFS assetstore with a replicaset, and 'gridfsshard' one with a sharding server. For any other value, use a filesystem assetstore. """ self.assetstoreType = assetstoreType dropTestDatabase(dropModels=dropModels) assetstoreName = os.environ.get('GIRDER_TEST_ASSETSTORE', 'test') assetstorePath = os.path.join( ROOT_DIR, 'tests', 'assetstore', assetstoreName) if assetstoreType == 'gridfs': # Name this as '_auto' to prevent conflict with assetstores created # within test methods gridfsDbName = 'girder_test_%s_assetstore_auto' % assetstoreName dropGridFSDatabase(gridfsDbName) self.assetstore = Assetstore().createGridFsAssetstore(name='Test', db=gridfsDbName) elif assetstoreType == 'gridfsrs': gridfsDbName = 'girder_test_%s_rs_assetstore_auto' % assetstoreName self.replicaSetConfig = mongo_replicaset.makeConfig() mongo_replicaset.startMongoReplicaSet(self.replicaSetConfig) self.assetstore = Assetstore().createGridFsAssetstore( name='Test', db=gridfsDbName, mongohost='mongodb://127.0.0.1:27070,127.0.0.1:27071,' '127.0.0.1:27072', replicaset='replicaset') elif assetstoreType == 'gridfsshard': gridfsDbName = 'girder_test_%s_shard_assetstore_auto' % assetstoreName self.replicaSetConfig = mongo_replicaset.makeConfig( port=27073, shard=True, sharddb=None) mongo_replicaset.startMongoReplicaSet(self.replicaSetConfig) self.assetstore = Assetstore().createGridFsAssetstore( name='Test', db=gridfsDbName, mongohost='mongodb://127.0.0.1:27073', shard='auto') elif assetstoreType == 's3': self.assetstore = Assetstore().createS3Assetstore( name='Test', bucket='bucketname', accessKeyId='test', secret='test', service=mockS3Server.service) else: dropFsAssetstore(assetstorePath) self.assetstore = Assetstore().createFilesystemAssetstore( name='Test', root=assetstorePath) addr = ':'.join(map(str, mockSmtp.address or ('localhost', 25))) settings = Setting() settings.set(SettingKey.SMTP_HOST, addr) settings.set(SettingKey.UPLOAD_MINIMUM_CHUNK_SIZE, 0) settings.set(SettingKey.PLUGINS_ENABLED, enabledPlugins) if os.environ.get('GIRDER_TEST_DATABASE_CONFIG'): setup_database.main(os.environ['GIRDER_TEST_DATABASE_CONFIG'])
def setUp(self, assetstoreType=None, dropModels=True): """ We want to start with a clean database each time, so we drop the test database before each test. We then add an assetstore so the file model can be used without 500 errors. :param assetstoreType: if 'gridfs' or 's3', use that assetstore. 'gridfsrs' uses a GridFS assetstore with a replicaset, and 'gridfsshard' one with a sharding server. For any other value, use a filesystem assetstore. """ self.assetstoreType = assetstoreType dropTestDatabase(dropModels=dropModels) assetstoreName = os.environ.get('GIRDER_TEST_ASSETSTORE', 'test') assetstorePath = os.path.join( ROOT_DIR, 'tests', 'assetstore', assetstoreName) if assetstoreType == 'gridfs': # Name this as '_auto' to prevent conflict with assetstores created # within test methods gridfsDbName = 'girder_test_%s_assetstore_auto' % assetstoreName.replace('.', '_') dropGridFSDatabase(gridfsDbName) self.assetstore = Assetstore().createGridFsAssetstore(name='Test', db=gridfsDbName) elif assetstoreType == 'gridfsrs': gridfsDbName = 'girder_test_%s_rs_assetstore_auto' % assetstoreName self.replicaSetConfig = mongo_replicaset.makeConfig() mongo_replicaset.startMongoReplicaSet(self.replicaSetConfig) self.assetstore = Assetstore().createGridFsAssetstore( name='Test', db=gridfsDbName, mongohost='mongodb://127.0.0.1:27070,127.0.0.1:27071,' '127.0.0.1:27072', replicaset='replicaset') elif assetstoreType == 'gridfsshard': gridfsDbName = 'girder_test_%s_shard_assetstore_auto' % assetstoreName self.replicaSetConfig = mongo_replicaset.makeConfig( port=27073, shard=True, sharddb=None) mongo_replicaset.startMongoReplicaSet(self.replicaSetConfig) self.assetstore = Assetstore().createGridFsAssetstore( name='Test', db=gridfsDbName, mongohost='mongodb://127.0.0.1:27073', shard='auto') elif assetstoreType == 's3': self.assetstore = Assetstore().createS3Assetstore( name='Test', bucket='bucketname', accessKeyId='test', secret='test', service=mockS3Server.service) else: dropFsAssetstore(assetstorePath) self.assetstore = Assetstore().createFilesystemAssetstore( name='Test', root=assetstorePath) addr = ':'.join(map(str, mockSmtp.address or ('localhost', 25))) settings = Setting() settings.set(SettingKey.SMTP_HOST, addr) settings.set(SettingKey.UPLOAD_MINIMUM_CHUNK_SIZE, 0) settings.set(SettingKey.PLUGINS_ENABLED, enabledPlugins) if os.environ.get('GIRDER_TEST_DATABASE_CONFIG'): setup_database.main(os.environ['GIRDER_TEST_DATABASE_CONFIG'])
def testLdapLogin(self): settings = Setting() self.assertEqual(settings.get(PluginSettings.SERVERS), []) with self.assertRaises(ValidationException): settings.set(PluginSettings.SERVERS, {}) settings.set(PluginSettings.SERVERS, [{ 'baseDn': 'cn=Users,dc=foo,dc=bar,dc=org', 'bindName': 'cn=foo,cn=Users,dc=foo,dc=bar,dc=org', 'password': '******', 'searchField': 'mail', 'uri': 'foo.bar.org:389' }]) with mock.patch('ldap.initialize', return_value=MockLdap()) as ldapInit: resp = self.request('/user/authentication', basicAuth='hello:world') self.assertEqual(len(ldapInit.mock_calls), 1) self.assertStatusOk(resp) # Register a new user user = resp.json['user'] self.assertEqual(user['email'], '*****@*****.**') self.assertEqual(user['firstName'], 'Foo') self.assertEqual(user['lastName'], 'Bar') self.assertEqual(user['login'], 'foobar') # Login as an existing user resp = self.request('/user/authentication', basicAuth='hello:world') self.assertStatusOk(resp) self.assertEqual(resp.json['user']['_id'], user['_id']) with mock.patch('ldap.initialize', return_value=MockLdap(bindFail=True)): resp = self.request('/user/authentication', basicAuth='hello:world') self.assertStatus(resp, 401) with mock.patch('ldap.initialize', return_value=MockLdap(searchFail=True)): resp = self.request('/user/authentication', basicAuth='hello:world') self.assertStatus(resp, 401) # Test fallback to logging in with core auth normalUser = User().createUser( login='******', firstName='Normal', lastName='User', email='*****@*****.**', password='******') with mock.patch('ldap.initialize', return_value=MockLdap(searchFail=True)): resp = self.request('/user/authentication', basicAuth='normal:normaluser') self.assertStatusOk(resp) self.assertEqual(str(normalUser['_id']), resp.json['user']['_id']) # Test registering from a record that only has a cn, no sn/givenName record = { 'cn': [b'Fizz Buzz'], 'mail': [b'*****@*****.**'], 'distinguishedName': [b'shouldbeignored'] } with mock.patch('ldap.initialize', return_value=MockLdap(record=record)): resp = self.request('/user/authentication', basicAuth='fizzbuzz:foo') self.assertStatusOk(resp) self.assertEqual(resp.json['user']['login'], 'fizz') self.assertEqual(resp.json['user']['firstName'], 'Fizz') self.assertEqual(resp.json['user']['lastName'], 'Buzz') # Test falling back to other name generation behavior (first+last name) record = { 'cn': [b'Fizz Buzz'], 'mail': [b'*****@*****.**'], 'distinguishedName': [b'shouldbeignored'] } with mock.patch('ldap.initialize', return_value=MockLdap(record=record)): resp = self.request('/user/authentication', basicAuth='fizzbuzz:foo') self.assertStatusOk(resp) self.assertEqual(resp.json['user']['login'], 'fizzbuzz') self.assertEqual(resp.json['user']['firstName'], 'Fizz') self.assertEqual(resp.json['user']['lastName'], 'Buzz')
def testLdapLogin(self): from girder.plugins.ldap.constants import PluginSettings settings = Setting() self.assertEqual(settings.get(PluginSettings.LDAP_SERVERS), []) with self.assertRaises(ValidationException): settings.set(PluginSettings.LDAP_SERVERS, {}) settings.set(PluginSettings.LDAP_SERVERS, [{ 'baseDn': 'cn=Users,dc=foo,dc=bar,dc=org', 'bindName': 'cn=foo,cn=Users,dc=foo,dc=bar,dc=org', 'password': '******', 'searchField': 'mail', 'uri': 'foo.bar.org:389' }]) with mock.patch('ldap.initialize', return_value=MockLdap()) as ldapInit: resp = self.request('/user/authentication', basicAuth='hello:world') self.assertEqual(len(ldapInit.mock_calls), 1) self.assertStatusOk(resp) # Register a new user user = resp.json['user'] self.assertEqual(user['email'], '*****@*****.**') self.assertEqual(user['firstName'], 'Foo') self.assertEqual(user['lastName'], 'Bar') self.assertEqual(user['login'], 'foobar') # Login as an existing user resp = self.request('/user/authentication', basicAuth='hello:world') self.assertStatusOk(resp) self.assertEqual(resp.json['user']['_id'], user['_id']) with mock.patch('ldap.initialize', return_value=MockLdap(bindFail=True)): resp = self.request('/user/authentication', basicAuth='hello:world') self.assertStatus(resp, 401) with mock.patch('ldap.initialize', return_value=MockLdap(searchFail=True)): resp = self.request('/user/authentication', basicAuth='hello:world') self.assertStatus(resp, 401) # Test fallback to logging in with core auth normalUser = User().createUser(login='******', firstName='Normal', lastName='User', email='*****@*****.**', password='******') with mock.patch('ldap.initialize', return_value=MockLdap(searchFail=True)): resp = self.request('/user/authentication', basicAuth='normal:normaluser') self.assertStatusOk(resp) self.assertEqual(str(normalUser['_id']), resp.json['user']['_id']) # Test registering from a record that only has a cn, no sn/givenName record = { 'cn': [b'Fizz Buzz'], 'mail': [b'*****@*****.**'], 'distinguishedName': [b'shouldbeignored'] } with mock.patch('ldap.initialize', return_value=MockLdap(record=record)): resp = self.request('/user/authentication', basicAuth='fizzbuzz:foo') self.assertStatusOk(resp) self.assertEqual(resp.json['user']['login'], 'fizz') self.assertEqual(resp.json['user']['firstName'], 'Fizz') self.assertEqual(resp.json['user']['lastName'], 'Buzz') # Test falling back to other name generation behavior (first+last name) record = { 'cn': [b'Fizz Buzz'], 'mail': [b'*****@*****.**'], 'distinguishedName': [b'shouldbeignored'] } with mock.patch('ldap.initialize', return_value=MockLdap(record=record)): resp = self.request('/user/authentication', basicAuth='fizzbuzz:foo') self.assertStatusOk(resp) self.assertEqual(resp.json['user']['login'], 'fizzbuzz') self.assertEqual(resp.json['user']['firstName'], 'Fizz') self.assertEqual(resp.json['user']['lastName'], 'Buzz')