コード例 #1
0
ファイル: system_test.py プロジェクト: girder/girder
    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')
コード例 #2
0
ファイル: system.py プロジェクト: data-exp-lab/girder
    def getCollectionCreationPolicyAccess(self):
        cpp = Setting().get('core.collection_create_policy')

        acList = {
            'users': [{'id': x} for x in cpp.get('users', [])],
            'groups': [{'id': x} for x in cpp.get('groups', [])]
        }

        for user in acList['users'][:]:
            userDoc = User().load(
                user['id'], force=True,
                fields=['firstName', 'lastName', 'login'])
            if userDoc is None:
                acList['users'].remove(user)
            else:
                user['login'] = userDoc['login']
                user['name'] = ' '.join((userDoc['firstName'], userDoc['lastName']))

        for grp in acList['groups'][:]:
            grpDoc = Group().load(
                grp['id'], force=True, fields=['name', 'description'])
            if grpDoc is None:
                acList['groups'].remove(grp)
            else:
                grp['name'] = grpDoc['name']
                grp['description'] = grpDoc['description']

        return acList
コード例 #3
0
ファイル: rest.py プロジェクト: data-exp-lab/girder
def _setCommonCORSHeaders():
    """
    Set CORS headers that should be passed back with either a preflight OPTIONS
    or a simple CORS request. We set these headers anytime there is an Origin
    header present since browsers will simply ignore them if the request is not
    cross-origin.
    """
    origin = cherrypy.request.headers.get('origin')
    if not origin:
        # If there is no origin header, this is not a cross origin request
        return

    allowed = Setting().get(SettingKey.CORS_ALLOW_ORIGIN)

    if allowed:
        setResponseHeader('Access-Control-Allow-Credentials', 'true')
        setResponseHeader(
            'Access-Control-Expose-Headers', Setting().get(SettingKey.CORS_EXPOSE_HEADERS))

        allowed_list = [o.strip() for o in allowed.split(',')]
        key = 'Access-Control-Allow-Origin'

        if len(allowed_list) == 1:
            setResponseHeader(key, allowed_list[0])
        elif origin in allowed_list:
            setResponseHeader(key, origin)
コード例 #4
0
ファイル: setting_test.py プロジェクト: girder/girder
    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')
コード例 #5
0
ファイル: setting_test.py プロジェクト: girder/girder
 def testUniqueIndex(self):
     settingModel = Setting()
     coll = settingModel.collection
     indices = coll.index_information()
     # Make sure we have just one index on key and that it specifies that it
     # is unique
     self.assertTrue(any(indices[index]['key'][0][0] == 'key' and
                     indices[index].get('unique') for index in indices))
     self.assertFalse(any(indices[index]['key'][0][0] == 'key' and
                      not indices[index].get('unique') for index in indices))
     # Delete that index, create a non-unique index, and make some duplicate
     # settings so that we can test that this will be corrected.
     coll.drop_index(next(index for index in indices
                          if indices[index]['key'][0][0] == 'key'))
     coll.create_index('key')
     for val in range(3, 8):
         coll.insert_one({'key': 'duplicate', 'value': val})
     # Check that we've broken things
     indices = coll.index_information()
     self.assertGreaterEqual(settingModel.get('duplicate'), 3)
     self.assertEqual(settingModel.find({'key': 'duplicate'}).count(), 5)
     self.assertFalse(any(indices[index]['key'][0][0] == 'key' and
                      indices[index].get('unique') for index in indices))
     self.assertTrue(any(indices[index]['key'][0][0] == 'key' and
                     not indices[index].get('unique') for index in indices))
     # Reconnecting the model should fix the issues we just created
     settingModel.reconnect()
     indices = coll.index_information()
     self.assertTrue(any(indices[index]['key'][0][0] == 'key' and
                     indices[index].get('unique') for index in indices))
     self.assertFalse(any(indices[index]['key'][0][0] == 'key' and
                      not indices[index].get('unique') for index in indices))
     self.assertEqual(settingModel.get('duplicate'), 3)
     self.assertEqual(settingModel.find({'key': 'duplicate'}).count(), 1)
コード例 #6
0
ファイル: mail_utils.py プロジェクト: data-exp-lab/girder
def _sendmail(event):
    from girder.models.setting import Setting

    msg = event.info['message']
    recipients = event.info['recipients']

    setting = Setting()
    smtp = _SMTPConnection(
        host=setting.get(SettingKey.SMTP_HOST, 'localhost'),
        port=setting.get(SettingKey.SMTP_PORT, None),
        encryption=setting.get(SettingKey.SMTP_ENCRYPTION, 'none'),
        username=setting.get(SettingKey.SMTP_USERNAME, None),
        password=setting.get(SettingKey.SMTP_PASSWORD, None)
    )

    logger.info('Sending email to %s through %s', ', '.join(recipients), smtp.host)

    with smtp:
        smtp.send(msg['From'], recipients, msg.as_string())
コード例 #7
0
ファイル: resource.py プロジェクト: data-exp-lab/girder
 def bindModels(self, event=None):
     """
     When the list of tracked provenance resources is changed, rebind the
     appropriate models to this instance of this class.
     :param event: the event when a setting is saved, or None to check the
                   binding.
     """
     if not event or event.name == 'provenance.initialize':
         pass
     elif event.name == 'model.setting.save.after':
         if not hasattr(event, "info"):
             return
         if event.info.get('key', '') != constants.PluginSettings.PROVENANCE_RESOURCES:
             return
     else:
         return
     resources = Setting().get(constants.PluginSettings.PROVENANCE_RESOURCES)
     if resources:
         resources = resources.replace(',', ' ').strip().split()
     else:
         resources = []
     resources = dict.fromkeys(resources)
     # Always include item
     resources['item'] = None
     # Exclude resources that should never have provenance
     for disallowedResource in ('model_base', 'notification', 'password',
                                'token'):
         if disallowedResource in resources:
             del resources[disallowedResource]
     self.unbindModels(resources)
     for resource in resources:
         if resource not in self.boundResources:
             events.bind('model.%s.save' % resource, 'provenance', self.resourceSaveHandler)
             events.bind(
                 'model.%s.copy.prepare' % resource, 'provenance', self.resourceCopyHandler)
             if hasattr(self.loadInfo['apiRoot'], resource):
                 getattr(self.loadInfo['apiRoot'], resource).route(
                     'GET', (':id', 'provenance'),
                     self.getGetHandler(resource))
             self.boundResources[resource] = True
コード例 #8
0
ファイル: base.py プロジェクト: data-exp-lab/girder
    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'])
コード例 #9
0
ファイル: rest.py プロジェクト: girder/girder
 def getSettings(self):
     settings = Setting()
     return {
         PluginSettings.MARKDOWN: settings.get(PluginSettings.MARKDOWN),
         PluginSettings.HEADER: settings.get(PluginSettings.HEADER),
         PluginSettings.SUBHEADER: settings.get(PluginSettings.SUBHEADER),
         PluginSettings.WELCOME_TEXT: settings.get(PluginSettings.WELCOME_TEXT),
         PluginSettings.LOGO: settings.get(PluginSettings.LOGO),
     }
コード例 #10
0
ファイル: system.py プロジェクト: data-exp-lab/girder
    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)
コード例 #11
0
ファイル: ldap_test.py プロジェクト: girder/girder
    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')
コード例 #12
0
    def testRegisterAndLoginBcrypt(self):
        """
        Test user registration and logging in.
        """
        cherrypy.config['auth']['hash_alg'] = 'bcrypt'
        # Set this to minimum so test runs faster.
        cherrypy.config['auth']['bcrypt_rounds'] = 4

        params = {
            'email': 'bad_email',
            'login': '******',
            'firstName': 'First',
            'lastName': 'Last',
            'password': '******'
        }
        # First test all of the required parameters.
        self.ensureRequiredParams(path='/user',
                                  method='POST',
                                  required=six.viewkeys(params))

        # Now test parameter validation
        resp = self.request(path='/user', method='POST', params=params)
        self.assertValidationError(resp, 'password')
        self.assertEqual(cherrypy.config['users']['password_description'],
                         resp.json['message'])

        params['password'] = '******'
        resp = self.request(path='/user', method='POST', params=params)
        self.assertValidationError(resp, 'login')

        # Make login something that violates the regex but doesn't contain @
        params['login'] = '******'
        resp = self.request(path='/user', method='POST', params=params)
        self.assertValidationError(resp, 'login')
        self.assertEqual(cherrypy.config['users']['login_description'],
                         resp.json['message'])

        params['login'] = '******'
        resp = self.request(path='/user', method='POST', params=params)
        self.assertValidationError(resp, 'email')

        # Now successfully create the user
        params['email'] = '*****@*****.**'
        resp = self.request(path='/user', method='POST', params=params)
        self.assertStatusOk(resp)
        self._verifyUserDocument(resp.json)

        user = User().load(resp.json['_id'], force=True)
        self.assertEqual(user['hashAlg'], 'bcrypt')

        # Try logging in without basic auth, should get 401
        resp = self.request(path='/user/authentication', method='GET')
        self.assertStatus(resp, 401)

        # Bad authentication header
        resp = self.request(path='/user/authentication',
                            method='GET',
                            additionalHeaders=[('Girder-Authorization',
                                                'Basic Not-Valid-64')])
        self.assertStatus(resp, 401)
        self.assertEqual('Invalid HTTP Authorization header',
                         resp.json['message'])
        resp = self.request(path='/user/authentication',
                            method='GET',
                            additionalHeaders=[('Girder-Authorization',
                                                'Basic NotValid')])
        self.assertStatus(resp, 401)
        self.assertEqual('Invalid HTTP Authorization header',
                         resp.json['message'])

        # Login with unregistered email
        resp = self.request(path='/user/authentication',
                            method='GET',
                            basicAuth='[email protected]:badpassword')
        self.assertStatus(resp, 401)
        self.assertEqual('Login failed.', resp.json['message'])

        # Correct email, but wrong password
        resp = self.request(path='/user/authentication',
                            method='GET',
                            basicAuth='[email protected]:badpassword')
        self.assertStatus(resp, 401)
        self.assertEqual('Login failed.', resp.json['message'])

        # Login successfully with email
        resp = self.request(path='/user/authentication',
                            method='GET',
                            basicAuth='[email protected]:good:password')
        self.assertStatusOk(resp)
        self.assertHasKeys(resp.json, ['authToken'])
        self.assertHasKeys(resp.json['authToken'], ['token', 'expires'])
        self._verifyAuthCookie(resp)

        # Invalid login
        resp = self.request(path='/user/authentication',
                            method='GET',
                            basicAuth='badlogin:good:password')
        self.assertStatus(resp, 401)
        self.assertEqual('Login failed.', resp.json['message'])

        # Login successfully with fallback Authorization header
        resp = self.request(path='/user/authentication',
                            method='GET',
                            basicAuth='goodlogin:good:password',
                            authHeader='Authorization')
        self.assertStatusOk(resp)

        # Test secure cookie validation
        with self.assertRaises(ValidationException):
            Setting().set(SettingKey.SECURE_COOKIE, 'bad value')
        # Set secure cookie value
        Setting().set(SettingKey.SECURE_COOKIE, True)

        # Login successfully with login
        resp = self.request(path='/user/authentication',
                            method='GET',
                            basicAuth='goodlogin:good:password')
        self.assertStatusOk(resp)

        # Make sure we got a nice (secure) cookie
        self._verifyAuthCookie(resp, secure=True)

        # Test user/me
        resp = self.request(path='/user/me', method='GET', user=user)
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['login'], user['login'])
コード例 #13
0
ファイル: describe.py プロジェクト: ziqiangxu/girder
 def _renderHTML(self):
     from girder.utility import server
     self.vars['apiRoot'] = server.getApiRoot()
     self.vars['staticPublicPath'] = server.getStaticPublicPath()
     self.vars['brandName'] = Setting().get(SettingKey.BRAND_NAME)
     return super(ApiDocs, self)._renderHTML()
コード例 #14
0
class HistogramResource(Resource):
    def __init__(self):
        super(HistogramResource, self).__init__()

        self.resourceName = 'histogram'

        self.route('GET', (), self.find)
        self.route('POST', (), self.createHistogram)
        self.route('DELETE', (':id', ), self.deleteHistogram)
        self.route('GET', (':id', ), self.getHistogram)
        self.route('GET', (':id', 'access'), self.getHistogramAccess)
        self.route('PUT', (':id', 'access'), self.updateHistogramAccess)
        self.route('GET', ('settings', ), self.getSettings)

        self.histogram = Histogram()

    @access.public(scope=TokenScope.DATA_READ)
    @filtermodel(Histogram)
    @autoDescribeRoute(
        Description('Search for histograms.').responseClass(
            Histogram, array=True).param(
                'itemId',
                'The item ID of the histogram source.',
                required=False).param('bins',
                                      'Number of bins in in the histogram.',
                                      required=False,
                                      dataType='integer').
        param('label',
              'Histogram is of a label image.',
              required=False,
              dataType='boolean').param(
                  'bitmask',
                  'Histogram is of a image with bitmask values.',
                  required=False,
                  dataType='boolean').param(
                      'jobId',
                      'The job ID of the task generating the histogram.',
                      required=False).param(
                          'fileId',
                          'The file ID of the histogram file.',
                          required=False).pagingParams(
                              defaultSort='_id').errorResponse().errorResponse(
                                  'No matching histograms were found.', 404))
    def find(self, itemId, bins, label, bitmask, jobId, fileId, limit, offset,
             sort):
        user = self.getCurrentUser()
        query = {}
        if itemId is not None:
            query['itemId'] = ObjectId(itemId)
        if bins is not None:
            query['bins'] = bins
        if label is not None:
            query['label'] = label
        if bitmask is not None:
            query['bitmask'] = bitmask
        if jobId is not None:
            query['jobId'] = ObjectId(jobId)
        if fileId is not None:
            query['fileId'] = ObjectId(fileId)
        return list(
            self.histogram.filterResultsByPermission(
                cursor=self.histogram.find(query, sort=sort),
                user=user,
                level=AccessType.READ,
                limit=limit,
                offset=offset))

    @access.user(scope=TokenScope.DATA_WRITE)
    # @filtermodel(model='job', plugin='jobs')
    @filtermodel(Histogram)
    @autoDescribeRoute(
        Description('Create a new histogram from an item.').modelParam(
            'itemId',
            'The ID of the source item.',
            paramType='formData',
            model=Item,
            level=AccessType.WRITE).param(
                'fileId', 'The ID of the source file.', required=False).param(
                    'notify',
                    'Trigger a notification when completed',
                    required=False,
                    dataType='boolean',
                    default=False).param(
                        'bins',
                        'Number of bins in the histogram',
                        required=False,
                        dataType='integer',
                        # FIXME: update
                        default=Setting().get(
                            PluginSettings.DEFAULT_BINS)).param(
                                'label',
                                'Image is a label (ignore zero values)',
                                required=False,
                                dataType='boolean',
                                default=False).param(
                                    'bitmask',
                                    'Image label values are bitmasks',
                                    required=False,
                                    dataType='boolean',
                                    default=False))
    def createHistogram(self, item, fileId, notify, bins, label, bitmask):
        user = self.getCurrentUser()
        token = self.getCurrentToken()
        if fileId is None:
            # files = list(Item().childFiles(item=item, limit=2))
            query = {
                'itemId':
                item['_id'],
                # 'mimeType': {'$regex': '^image/tiff'}
                # query should find the same file(tiff) used for creating histogram
                # but this will always find most recent json histogram
                '$or': [{
                    'mimeType': {
                        '$regex': '^image/'
                    }
                }, {
                    'mimeType': 'application/octet-stream'
                }, {
                    'exts': ['tif']
                }],
            }
            files = list(File().find(query, limit=2))
            if len(files) >= 1:
                fileId = str(files[0]['_id'])
        if not fileId:
            raise RestException('Missing "fileId" parameter.')

        file_ = File().load(fileId, user=user, level=AccessType.READ, exc=True)
        return self.histogram.createHistogramJob(item,
                                                 file_,
                                                 user=user,
                                                 token=token,
                                                 notify=notify,
                                                 bins=bins,
                                                 label=label,
                                                 bitmask=bitmask)

    @access.user(scope=TokenScope.DATA_OWN)
    @filtermodel(Histogram)
    @autoDescribeRoute(
        Description('Delete a histogram.').modelParam(
            'id', model=Histogram, level=AccessType.WRITE).errorResponse(
                'ID was invalid.').errorResponse(
                    'Write access was denied for the histogram.', 403))
    def deleteHistogram(self, histogram):
        self.histogram.remove(histogram)

    @access.public(scope=TokenScope.DATA_READ)
    @filtermodel(Histogram)
    @autoDescribeRoute(
        Description('Get histogram by ID.').responseClass(
            Histogram).modelParam(
                'id', model=Histogram, level=AccessType.READ).errorResponse(
                    'ID was invalid.').errorResponse(
                        'Read access was denied for the histogram.', 403))
    def getHistogram(self, histogram):
        return histogram

    @access.user(scope=TokenScope.DATA_OWN)
    @filtermodel(Histogram)
    @autoDescribeRoute(
        Description('Get the access control list for a histogram.').modelParam(
            'id', model=Histogram, level=AccessType.ADMIN).errorResponse(
                'ID was invalid.').errorResponse(
                    'Admin access was denied for the histogram.', 403))
    def getHistogramAccess(self, histogram):
        return self.histogram.getFullAccessList(histogram)

    @access.user(scope=TokenScope.DATA_OWN)
    @filtermodel(Histogram)
    @autoDescribeRoute(
        Description('Update the access control list for a histogram.').
        responseClass(Histogram).modelParam('id',
                                            model=Histogram,
                                            level=AccessType.ADMIN).
        jsonParam('access', 'The JSON-encoded access control list.').param(
            'public',
            'Whether the histogram should be publicly visible.',
            dataType='boolean',
            required=False).errorResponse('ID was invalid.').errorResponse(
                'Admin access was denied for the histogram.', 403))
    def updateHistogramAccess(self, histogram, access, public):
        self.histogram.setPublic(histogram, public)
        return self.histogram.setAccessList(histogram,
                                            access,
                                            save=True,
                                            user=self.getCurrentUser())

    @access.public
    @autoDescribeRoute(Description('Getting histogram settings.'))
    def getSettings(self):
        settings = Setting()
        return {
            PluginSettings.DEFAULT_BINS:
            settings.get(PluginSettings.DEFAULT_BINS),
        }
コード例 #15
0
 def getClientSecretSetting(self):
     return Setting().get(constants.PluginSettings.GLOBUS_CLIENT_SECRET)
コード例 #16
0
ファイル: linkedin.py プロジェクト: wphicks/girder
 def getClientSecretSetting(self):
     return Setting().get(PluginSettings.LINKEDIN_CLIENT_SECRET)
コード例 #17
0
ファイル: routes_test.py プロジェクト: wegiangb/girder
    def testCORS(self):
        testServer.root.api.v1.dummy = DummyResource()

        # When no origin header is passed, we shouldn't receive CORS headers
        resp = self.request(path='/dummy/test')
        self.assertStatusOk(resp)
        self.assertFalse('Access-Control-Allow-Origin' in resp.headers)
        self.assertFalse('Access-Control-Allow-Credentials' in resp.headers)

        # If no origins are allowed, we should not get an allow origin header
        resp = self.request(path='/dummy/test', additionalHeaders=[
            ('Origin', 'http://foo.com')
        ])
        self.assertStatusOk(resp)
        self.assertFalse('Access-Control-Allow-Origin' in resp.headers)

        # Request from a non-allowed Origin
        Setting().set(SettingKey.CORS_ALLOW_ORIGIN, 'http://kitware.com')
        resp = self.request(path='/dummy/test', additionalHeaders=[
            ('Origin', 'http://foo.com')
        ])
        self.assertNotIn('Access-Control-Allow-Origin', resp.headers)
        self.assertEqual(resp.headers['Access-Control-Allow-Credentials'], 'true')

        # Simulate a preflight request; we should get back several headers
        Setting().set(SettingKey.CORS_ALLOW_METHODS, 'POST')
        resp = self.request(
            path='/dummy/test', method='OPTIONS', additionalHeaders=[
                ('Origin', 'http://foo.com')
            ], isJson=False
        )
        self.assertStatusOk(resp)
        self.assertEqual(self.getBody(resp), '')

        self.assertNotIn('Access-Control-Allow-Origin', resp.headers)
        self.assertEqual(resp.headers['Access-Control-Allow-Credentials'], 'true')
        self.assertEqual(resp.headers['Access-Control-Allow-Headers'],
                         SettingDefault.defaults[SettingKey.CORS_ALLOW_HEADERS])
        self.assertEqual(resp.headers['Access-Control-Allow-Methods'], 'POST')

        # Make an actual preflight request with query parameters; CherryPy 11.1
        # introduced a bug where this would fail with a 405.
        resp = requests.options(
            'http://127.0.0.1:%s/api/v1/folder?key=value' % os.environ['GIRDER_TEST_PORT'])
        self.assertEqual(resp.status_code, 200)

        # Set multiple allowed origins
        Setting().set(SettingKey.CORS_ALLOW_ORIGIN, 'http://foo.com, http://bar.com')
        resp = self.request(
            path='/dummy/test', method='GET', additionalHeaders=[
                ('Origin', 'http://bar.com')
            ], isJson=False)
        self.assertEqual(resp.headers['Access-Control-Allow-Origin'], 'http://bar.com')

        resp = self.request(
            path='/dummy/test', method='GET', additionalHeaders=[
                ('Origin', 'http://invalid.com')
            ], isJson=False)
        self.assertNotIn('Access-Control-Allow-Origin', resp.headers)

        # Test behavior of '*' allowed origin
        Setting().set(SettingKey.CORS_ALLOW_ORIGIN, 'http://foo.com,*')
        resp = self.request(
            path='/dummy/test', method='GET', additionalHeaders=[
                ('Origin', 'http://bar.com')
            ], isJson=False)
        self.assertEqual(resp.headers['Access-Control-Allow-Origin'], '*')

        resp = self.request(
            path='/dummy/test', method='GET', additionalHeaders=[
                ('Origin', 'http://foo.com')
            ], isJson=False)
        self.assertEqual(resp.headers['Access-Control-Allow-Origin'], 'http://foo.com')
コード例 #18
0
ファイル: meta.py プロジェクト: pearcetm/HistomicsUI
 def getTCGACollection(self):
     """Get the unique TCGA collection from the settings collection."""
     tcga = Setting().get(TCGACollectionSettingKey)
     if tcga is None:
         raise Exception('TCGA collection id not initialized in settings')
     return Collection().load(tcga, force=True)
コード例 #19
0
 def defaultMaxSize(self):
     return int(Setting().get(
         PluginSettings.LARGE_IMAGE_MAX_SMALL_IMAGE_SIZE))
コード例 #20
0
ファイル: system_test.py プロジェクト: wphicks/girder
    def testSettings(self):
        users = self.users

        # Only admins should be able to get or set settings
        for method in ('GET', 'PUT', 'DELETE'):
            resp = self.request(path='/system/setting',
                                method=method,
                                params={
                                    'key': 'foo',
                                    'value': 'bar'
                                },
                                user=users[1])
            self.assertStatus(resp, 403)

        # Only valid setting keys should be allowed
        resp = self.request(path='/system/setting',
                            method='PUT',
                            params={
                                'key': 'foo',
                                'value': 'bar'
                            },
                            user=users[0])
        self.assertStatus(resp, 400)
        self.assertEqual(resp.json['field'], 'key')

        # Only a valid JSON list is permitted
        resp = self.request(path='/system/setting',
                            method='GET',
                            params={'list': json.dumps('not_a_list')},
                            user=users[0])
        self.assertStatus(resp, 400)

        resp = self.request(path='/system/setting',
                            method='PUT',
                            params={'list': json.dumps('not_a_list')},
                            user=users[0])
        self.assertStatus(resp, 400)

        # Set an invalid setting value, should fail
        resp = self.request(path='/system/setting',
                            method='PUT',
                            params={
                                'key': SettingKey.BANNER_COLOR,
                                'value': 'bar'
                            },
                            user=users[0])
        self.assertStatus(resp, 400)
        self.assertEqual(resp.json['message'],
                         'The banner color must be a hex color triplet')

        # Set a valid value
        resp = self.request(path='/system/setting',
                            method='PUT',
                            params={
                                'key': SettingKey.BANNER_COLOR,
                                'value': '#121212'
                            },
                            user=users[0])
        self.assertStatusOk(resp)

        # We should now be able to retrieve it
        resp = self.request(path='/system/setting',
                            method='GET',
                            params={'key': SettingKey.BANNER_COLOR},
                            user=users[0])
        self.assertStatusOk(resp)
        self.assertEqual(resp.json, '#121212')

        # We should now clear the setting
        resp = self.request(path='/system/setting',
                            method='DELETE',
                            params={'key': SettingKey.BANNER_COLOR},
                            user=users[0])
        self.assertStatusOk(resp)

        # Setting should now be default
        setting = Setting().get(SettingKey.BANNER_COLOR)
        self.assertEqual(setting,
                         SettingDefault.defaults[SettingKey.BANNER_COLOR])

        # We should also be able to put several setting using a JSON list
        resp = self.request(path='/system/setting',
                            method='PUT',
                            params={
                                'list':
                                json.dumps([
                                    {
                                        'key': SettingKey.BANNER_COLOR,
                                        'value': '#121212'
                                    },
                                    {
                                        'key': SettingKey.COOKIE_LIFETIME,
                                        'value': None
                                    },
                                ])
                            },
                            user=users[0])
        self.assertStatusOk(resp)

        # We can get a list as well
        resp = self.request(path='/system/setting',
                            method='GET',
                            params={
                                'list':
                                json.dumps([
                                    SettingKey.BANNER_COLOR,
                                    SettingKey.COOKIE_LIFETIME,
                                ])
                            },
                            user=users[0])
        self.assertStatusOk(resp)
        self.assertEqual(resp.json[SettingKey.BANNER_COLOR], '#121212')

        # Try to set each key in turn to test the validation.  First test with
        # am invalid value, then test with the default value.  If the value
        # 'bad' won't trigger a validation error, the key should be present in
        # the badValues table.
        badValues = {
            SettingKey.BRAND_NAME: '',
            SettingKey.BANNER_COLOR: '',
            SettingKey.EMAIL_FROM_ADDRESS: '',
            SettingKey.PRIVACY_NOTICE: '',
            SettingKey.CONTACT_EMAIL_ADDRESS: '',
            SettingKey.EMAIL_HOST: {},
            SettingKey.SMTP_HOST: '',
            SettingKey.SMTP_PASSWORD: {},
            SettingKey.SMTP_USERNAME: {},
            SettingKey.CORS_ALLOW_ORIGIN: {},
            SettingKey.CORS_ALLOW_METHODS: {},
            SettingKey.CORS_ALLOW_HEADERS: {},
            SettingKey.CORS_EXPOSE_HEADERS: {},
        }
        allKeys = dict.fromkeys(six.viewkeys(SettingDefault.defaults))
        allKeys.update(badValues)
        for key in allKeys:
            resp = self.request(path='/system/setting',
                                method='PUT',
                                params={
                                    'key': key,
                                    'value': badValues.get(key, 'bad')
                                },
                                user=users[0])
            self.assertStatus(resp, 400)
            resp = self.request(path='/system/setting',
                                method='PUT',
                                params={
                                    'key':
                                    key,
                                    'value':
                                    json.dumps(
                                        SettingDefault.defaults.get(key, ''))
                                },
                                user=users[0])
            self.assertStatusOk(resp)
            resp = self.request(
                path='/system/setting',
                method='PUT',
                params={'list': json.dumps([{
                    'key': key,
                    'value': None
                }])},
                user=users[0])
            self.assertStatusOk(resp)
コード例 #21
0
    def testAnnotationHistoryEndpoints(self, server, user, admin):
        privateFolder = utilities.namedFolder(admin, 'Private')
        Setting().set(constants.PluginSettings.LARGE_IMAGE_ANNOTATION_HISTORY,
                      True)
        item = Item().createItem('sample', admin, privateFolder)
        # Create an annotation with some history
        annot = Annotation().createAnnotation(item, admin,
                                              copy.deepcopy(sampleAnnotation))
        annot['annotation']['name'] = 'First Change'
        annot['annotation']['elements'].extend([
            {
                'type': 'point',
                'center': [20.0, 25.0, 0]
            },
            {
                'type': 'point',
                'center': [10.0, 24.0, 0]
            },
            {
                'type': 'point',
                'center': [25.5, 23.0, 0]
            },
        ])
        annot = Annotation().save(annot)
        # simulate a concurrent save
        dup = Annotation().findOne({'_id': annot['_id']})
        dup['_annotationId'] = dup.pop('_id')
        dup['_active'] = False
        Annotation().collection.insert_one(dup)
        # Save again
        annot['annotation']['name'] = 'Second Change'
        annot['annotation']['elements'].pop(2)
        annot = Annotation().save(annot)

        # Test the list of versions
        resp = server.request('/annotation/%s/history' % annot['_id'],
                              user=user)
        assert utilities.respStatus(resp) == 200
        assert resp.json == []
        resp = server.request('/annotation/%s/history' % annot['_id'],
                              user=admin)
        assert utilities.respStatus(resp) == 200
        assert len(resp.json) == 3
        versions = resp.json

        # Test getting a specific version
        resp = server.request('/annotation/%s/history/%s' %
                              (annot['_id'], versions[1]['_version']),
                              user=user)
        assert utilities.respStatus(resp) == 403
        resp = server.request('/annotation/%s/history/%s' %
                              (annot['_id'], versions[1]['_version']),
                              user=admin)
        assert utilities.respStatus(resp) == 200
        assert resp.json['_annotationId'] == str(annot['_id'])
        assert len(resp.json['annotation']['elements']) == 4
        resp = server.request('/annotation/%s/history/%s' %
                              (annot['_id'], versions[0]['_version'] + 1),
                              user=admin)
        assert utilities.respStatus(resp) == 400

        # Test revert
        resp = server.request('/annotation/%s/history/revert' % (annot['_id']),
                              method='PUT',
                              user=user)
        assert utilities.respStatus(resp) == 403
        resp = server.request('/annotation/%s/history/revert' % (annot['_id']),
                              method='PUT',
                              user=admin,
                              params={'version': versions[0]['_version'] + 1})
        assert utilities.respStatus(resp) == 400
        resp = server.request('/annotation/%s/history/revert' % (annot['_id']),
                              method='PUT',
                              user=admin,
                              params={'version': versions[1]['_version']})
        assert utilities.respStatus(resp) == 200
        loaded = Annotation().load(annot['_id'], user=admin)
        assert len(loaded['annotation']['elements']) == 4
コード例 #22
0
 def get_extra_hosts_setting():
     return Setting().get(constants.PluginSettings.DATAVERSE_EXTRA_HOSTS)
コード例 #23
0
 def get_base_url_setting():
     return Setting().get(constants.PluginSettings.DATAVERSE_URL)
コード例 #24
0
ファイル: describe.py プロジェクト: EinsteinToolkit/datavault
 def _onSettingRemove(self, event):
     settingDoc = event.info
     if settingDoc['key'] == SettingKey.BRAND_NAME:
         self.updateHtmlVars(
             {'brandName': Setting().getDefault(SettingKey.BRAND_NAME)})
コード例 #25
0
ファイル: system.py プロジェクト: tymiao1220/girder
 def getSetting(self, key, list):
     if list is not None:
         return {k: Setting().get(k) for k in list}
     else:
         self.requireParams({'key': key})
         return Setting().get(key)
コード例 #26
0
 def getClientIdSetting(self):
     return Setting().get(constants.PluginSettings.GLOBUS_CLIENT_ID)
コード例 #27
0
ファイル: system.py プロジェクト: tymiao1220/girder
 def unsetSetting(self, key):
     return Setting().unset(key)
コード例 #28
0
ファイル: linkedin.py プロジェクト: wphicks/girder
 def getClientIdSetting(self):
     return Setting().get(PluginSettings.LINKEDIN_CLIENT_ID)
コード例 #29
0
ファイル: configuration.py プロジェクト: OpenChemistry/edp
    def get(self):
        config = {
            'deployment': Setting().get(constants.CONFIGURATION_DEPLOYMENT),
            'license': Setting().get(constants.CONFIGURATION_LICENSE),
            'privacy': Setting().get(constants.CONFIGURATION_PRIVACY),
            'showMenu': Setting().get(constants.CONFIGURATION_SHOW_MENU, True),
            'showSearch': Setting().get(constants.CONFIGURATION_SHOW_SEARCH,
                                        True)
        }

        if Setting().get(
                constants.CONFIGURATION_HEADER_LEFT_LOGO_ID) is not None:
            config['headerLeftLogoFileId'] = Setting().get(
                constants.CONFIGURATION_HEADER_LEFT_LOGO_ID)

        if Setting().get(
                constants.CONFIGURATION_HEADER_RIGHT_LOGO_ID) is not None:
            config['headerRightLogoFileId'] = Setting().get(
                constants.CONFIGURATION_HEADER_RIGHT_LOGO_ID)

        if Setting().get(
                constants.CONFIGURATION_HEADER_RIGHT_LOGO_URL) is not None:
            config['headerRightLogoUrl'] = Setting().get(
                constants.CONFIGURATION_HEADER_RIGHT_LOGO_URL)

        if Setting().get(constants.CONFIGURATION_FAVICON_ID) is not None:
            config['faviconFileId'] = Setting().get(
                constants.CONFIGURATION_FAVICON_ID)

        if Setting().get(constants.CONFIGURATION_FOOTER_LOGO_ID) is not None:
            config['footerLogoFileId'] = Setting().get(
                constants.CONFIGURATION_FOOTER_LOGO_ID)

        if Setting().get(constants.CONFIGURATION_FOOTER_LOGO_URL) is not None:
            config['footerLogoUrl'] = Setting().get(
                constants.CONFIGURATION_FOOTER_LOGO_URL)

        return config
コード例 #30
0
ファイル: user_test.py プロジェクト: tymiao1220/girder
    def testAccountApproval(self):
        admin = User().createUser('admin', 'password', 'Admin', 'Admin',
                                  '*****@*****.**')

        Setting().set(SettingKey.REGISTRATION_POLICY, 'approve')

        self.assertTrue(base.mockSmtp.isMailQueueEmpty())

        user = User().createUser('user', 'password', 'User', 'User',
                                 '*****@*****.**')

        # pop email
        self.assertTrue(base.mockSmtp.waitForMail())
        base.mockSmtp.getMail(parse=True)

        # cannot login without being approved
        resp = self.request('/user/authentication', basicAuth='user:password')
        self.assertStatus(resp, 401)
        self.assertTrue(resp.json['extra'] == 'accountApproval')

        # ensure only admins can change status
        path = '/user/%s' % user['_id']
        resp = self.request(path=path,
                            method='PUT',
                            user=user,
                            params={
                                'firstName': user['firstName'],
                                'lastName': user['lastName'],
                                'email': user['email'],
                                'status': 'enabled'
                            })
        self.assertStatus(resp, 403)
        self.assertEqual(resp.json['message'],
                         'Only admins may change status.')

        # approve account
        path = '/user/%s' % user['_id']
        resp = self.request(path=path,
                            method='PUT',
                            user=admin,
                            params={
                                'firstName': user['firstName'],
                                'lastName': user['lastName'],
                                'email': user['email'],
                                'status': 'enabled'
                            })
        self.assertStatusOk(resp)

        # pop email
        self.assertTrue(base.mockSmtp.waitForMail())
        base.mockSmtp.getMail(parse=True)

        # can now login
        resp = self.request('/user/authentication', basicAuth='user:password')
        self.assertStatusOk(resp)

        # disable account
        path = '/user/%s' % user['_id']
        resp = self.request(path=path,
                            method='PUT',
                            user=admin,
                            params={
                                'firstName': user['firstName'],
                                'lastName': user['lastName'],
                                'email': user['email'],
                                'status': 'disabled'
                            })
        self.assertStatusOk(resp)

        # cannot login again
        resp = self.request('/user/authentication', basicAuth='user:password')
        self.assertStatus(resp, 401)
        self.assertEqual(resp.json['extra'], 'disabled')
コード例 #31
0
 def testGeneralSettings(self, server, admin, user):
     self.makeResources(admin)
     settings = [{
         'key': PluginSettings.HUI_WEBROOT_PATH,
         'initial': 'histomics',
         'bad': {
             'girder': 'not be "girder"',
             '': 'not be empty'
         },
         'good': {
             'alternate1': 'alternate1'
         },
     }, {
         'key': PluginSettings.HUI_BRAND_NAME,
         'initial': 'HistomicsUI',
         'bad': {
             '': 'not be empty'
         },
         'good': {
             'Alternate': 'Alternate'
         },
     }, {
         'key': PluginSettings.HUI_BRAND_COLOR,
         'initial': '#777777',
         'bad': {
             '': 'not be empty',
             'white': 'be a hex color',
             '#777': 'be a hex color'
         },
         'good': {
             '#000000': '#000000'
         },
     }, {
         'key': PluginSettings.HUI_BANNER_COLOR,
         'initial': '#f8f8f8',
         'bad': {
             '': 'not be empty',
             'white': 'be a hex color',
             '#777': 'be a hex color'
         },
         'good': {
             '#000000': '#000000'
         },
     }]
     for setting in settings:
         key = setting['key']
         assert Setting().get(key) == setting['initial']
         for badval in setting.get('bad', {}):
             with pytest.raises(ValidationException,
                                match=setting['bad'][badval]):
                 Setting().set(key, badval)
         for badval in setting.get('badjson', []):
             with pytest.raises(ValidationException,
                                match=badval['return']):
                 Setting().set(key, badval['value'])
         for goodval in setting.get('good', {}):
             assert Setting().set(
                 key, goodval)['value'] == setting['good'][goodval]
         for goodval in setting.get('goodjson', []):
             assert Setting().set(
                 key, goodval['value'])['value'] == goodval['return']
コード例 #32
0
 def getSettings(self):
     settings = Setting()
     return {
         PluginSettings.DEFAULT_BINS:
         settings.get(PluginSettings.DEFAULT_BINS),
     }
コード例 #33
0
 def testQuarantine(self, server, admin, user):
     publicFolder = Folder().childFolders(  # noqa: B305
         user, 'user', filters={
             'name': 'Public'
         }).next()
     adminFolder = Folder().childFolders(  # noqa: B305
         admin, 'user', filters={
             'name': 'Public'
         }).next()
     privateFolder = Folder().childFolders(  # noqa: B305
         admin,
         'user',
         filters={
             'name': 'Private'
         },
         user=admin).next()
     items = [
         Item().createItem(name, creator, folder)
         for name, creator, folder in [
             ('userPublic1', user, publicFolder),
             ('userPublic2', user, publicFolder),
             ('adminPublic1', admin, adminFolder),
             ('adminPublic2', admin, adminFolder),
             ('adminPrivate1', admin, privateFolder),
             ('adminPrivate2', admin, privateFolder),
         ]
     ]
     resp = server.request(method='PUT',
                           path='/histomicsui/quarantine/%s' %
                           str(items[0]['_id']))
     assert utilities.respStatus(resp) == 401
     assert 'Write access denied' in resp.json['message']
     resp = server.request(method='PUT',
                           user=user,
                           path='/histomicsui/quarantine/%s' %
                           str(items[0]['_id']))
     assert utilities.respStatus(resp) == 400
     assert 'The quarantine folder is not configure' in resp.json['message']
     key = PluginSettings.HUI_QUARANTINE_FOLDER
     Setting().set(key, str(privateFolder['_id']))
     resp = server.request(method='PUT',
                           user=user,
                           path='/histomicsui/quarantine/%s' %
                           str(items[0]['_id']))
     assert utilities.respStatus(resp) == 200
     resp = server.request(method='PUT',
                           user=user,
                           path='/histomicsui/quarantine/%s' %
                           str(items[0]['_id']))
     assert utilities.respStatus(resp) == 403
     assert 'Write access denied' in resp.json['message']
     resp = server.request(method='PUT',
                           user=user,
                           path='/histomicsui/quarantine/%s' %
                           str(items[2]['_id']))
     assert utilities.respStatus(resp) == 403
     assert 'Write access denied' in resp.json['message']
     resp = server.request(method='PUT',
                           user=admin,
                           path='/histomicsui/quarantine/%s' %
                           str(items[2]['_id']))
     assert utilities.respStatus(resp) == 200
     resp = server.request(method='PUT',
                           user=admin,
                           path='/histomicsui/quarantine/%s' %
                           str(items[4]['_id']))
     assert utilities.respStatus(resp) == 400
     assert 'already in the quarantine' in resp.json['message']
     # Restore
     resp = server.request(method='PUT',
                           user=admin,
                           path='/histomicsui/quarantine/%s/restore' %
                           str(items[1]['_id']))
     assert utilities.respStatus(resp) == 400
     assert 'no quarantine record' in resp.json['message']
     resp = server.request(method='PUT',
                           path='/histomicsui/quarantine/%s/restore' %
                           str(items[0]['_id']))
     assert utilities.respStatus(resp) == 401
     assert 'Write access denied' in resp.json['message']
     resp = server.request(method='PUT',
                           user=user,
                           path='/histomicsui/quarantine/%s/restore' %
                           str(items[0]['_id']))
     assert utilities.respStatus(resp) == 403
     assert 'Write access denied' in resp.json['message']
     resp = server.request(method='PUT',
                           user=admin,
                           path='/histomicsui/quarantine/%s/restore' %
                           str(items[0]['_id']))
     assert utilities.respStatus(resp) == 200
     resp = server.request(method='PUT',
                           user=admin,
                           path='/histomicsui/quarantine/%s/restore' %
                           str(items[0]['_id']))
     assert utilities.respStatus(resp) == 400
     assert 'no quarantine record' in resp.json['message']
     resp = server.request(method='PUT',
                           user=user,
                           path='/histomicsui/quarantine/%s' %
                           str(items[0]['_id']))
     assert utilities.respStatus(resp) == 200
コード例 #34
0
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()
コード例 #35
0
    def testGetLicenses(self):
        """
        Test getting list of licenses.
        """
        # Get default settings
        resp = self.request(path='/item/licenses',
                            user=self.user,
                            params={'default': True})
        self.assertStatusOk(resp)
        self.assertGreater(len(resp.json), 1)
        self.assertIn('category', resp.json[0])
        self.assertIn('licenses', resp.json[0])
        self.assertGreater(len(resp.json[0]['licenses']), 8)
        self.assertIn('name', resp.json[0]['licenses'][0])
        self.assertGreater(len(resp.json[0]['licenses'][0]['name']), 0)
        self.assertIn('name', resp.json[0]['licenses'][1])
        self.assertGreater(len(resp.json[0]['licenses'][1]['name']), 0)

        # Get current settings
        resp = self.request(path='/item/licenses', user=self.user)
        self.assertStatusOk(resp)
        self.assertGreater(len(resp.json), 1)
        self.assertIn('category', resp.json[0])
        self.assertIn('licenses', resp.json[0])
        self.assertGreater(len(resp.json[0]['licenses']), 8)
        self.assertIn('name', resp.json[0]['licenses'][0])
        self.assertGreater(len(resp.json[0]['licenses'][0]['name']), 0)
        self.assertIn('name', resp.json[0]['licenses'][1])
        self.assertGreater(len(resp.json[0]['licenses'][1]['name']), 0)

        # Change licenses
        Setting().set(PluginSettings.LICENSES,
                      [{
                          'category': 'A',
                          'licenses': [{
                              'name': '1'
                          }]
                      }, {
                          'category': 'B',
                          'licenses': [{
                              'name': '2'
                          }, {
                              'name': '3'
                          }]
                      }])

        # Get default settings after changing licenses
        resp = self.request(path='/item/licenses',
                            user=self.user,
                            params={'default': True})
        self.assertStatusOk(resp)
        self.assertStatusOk(resp)
        self.assertGreater(len(resp.json), 1)
        self.assertIn('category', resp.json[0])
        self.assertIn('licenses', resp.json[0])
        self.assertGreater(len(resp.json[0]['licenses']), 8)
        self.assertIn('name', resp.json[0]['licenses'][0])
        self.assertGreater(len(resp.json[0]['licenses'][0]['name']), 0)
        self.assertIn('name', resp.json[0]['licenses'][1])
        self.assertGreater(len(resp.json[0]['licenses'][1]['name']), 0)

        # Get current settings after changing licenses
        resp = self.request(path='/item/licenses', user=self.user)
        self.assertStatusOk(resp)
        six.assertCountEqual(self, resp.json,
                             [{
                                 'category': 'A',
                                 'licenses': [{
                                     'name': '1'
                                 }]
                             }, {
                                 'category': 'B',
                                 'licenses': [{
                                     'name': '2'
                                 }, {
                                     'name': '3'
                                 }]
                             }])
コード例 #36
0
def testRouteTableValidationSuccess(value, db):
    Setting().validate({'key': SettingKey.ROUTE_TABLE, 'value': value})
コード例 #37
0
    def testLicensesSettingValidation(self):
        """
        Test validation of licenses setting.
        """
        # Test valid settings
        Setting().set(PluginSettings.LICENSES, [])
        Setting().set(PluginSettings.LICENSES, [{
            'category': 'A',
            'licenses': []
        }])
        Setting().set(PluginSettings.LICENSES, [{
            'category': 'A',
            'licenses': [{
                'name': '1'
            }]
        }])
        Setting().set(PluginSettings.LICENSES,
                      [{
                          'category': 'A',
                          'licenses': [{
                              'name': '1'
                          }, {
                              'name': '2'
                          }]
                      }])
        Setting().set(PluginSettings.LICENSES, [{
            'category': 'A',
            'licenses': []
        }, {
            'category': 'B',
            'licenses': [{
                'name': '1'
            }]
        }])
        Setting().set(PluginSettings.LICENSES,
                      [{
                          'category': 'A',
                          'licenses': []
                      }, {
                          'category': 'B',
                          'licenses': [{
                              'name': '1'
                          }, {
                              'name': '2'
                          }]
                      }])

        # Test invalid top-level types
        for val in (None, 1, '', {}, [{}]):
            self.assertRaises(ValidationException,
                              Setting().set, PluginSettings.LICENSES, val)

        # Test invalid category types
        for category, licenses in ((None, []), (1, []), ('', []), ({}, [])):
            self.assertRaises(ValidationException,
                              Setting().set, PluginSettings.LICENSES,
                              [{
                                  'category': category,
                                  'licenses': licenses
                              }])

        # Test invalid licenses types
        for val in (None, {}, [1], ['']):
            self.assertRaises(ValidationException,
                              Setting().set, PluginSettings.LICENSES,
                              [{
                                  'category': 'A',
                                  'licenses': val
                              }])

        # Test invalid license names
        for val in (None, 1, '', {}, []):
            self.assertRaises(ValidationException,
                              Setting().set, PluginSettings.LICENSES,
                              [{
                                  'category': 'A',
                                  'licenses': [{
                                      'name': val
                                  }]
                              }])
コード例 #38
0
def testRouteTableValidationFailure(value, err, db):
    with pytest.raises(ValidationException, match=err):
        Setting().validate({'key': SettingKey.ROUTE_TABLE, 'value': value})
コード例 #39
0
    def testLdapLogin(self):
        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')
コード例 #40
0
 def has_task_folder():
     return Setting().get(
         PluginSettings.SLICER_CLI_WEB_TASK_FOLDER) is not None
コード例 #41
0
    def _testQuota(self, model, resource, user):
        """
        Test quota policies for a specified resource.

        :param model: either 'user' or 'collection'.
        :param resource: the document for the resource to test.
        :param user: user to use for authorization.
        """
        Setting().set(SettingKey.UPLOAD_MINIMUM_CHUNK_SIZE, 0)
        resp = self.request(path='/folder',
                            method='GET',
                            user=user,
                            params={
                                'parentType': model,
                                'parentId': resource['_id']
                            })
        self.assertStatusOk(resp)
        self.assertGreaterEqual(len(resp.json), 1)
        folder = resp.json[0]
        # Start by uploading one file so that there is some use
        self._uploadFile('First upload', folder, size=1024)
        # Set a policy limiting things to 4 kb, then a 4 kb file should fail
        self._setPolicy({
            'fileSizeQuota': 4096,
            'useQuotaDefault': False
        }, model, resource, user)
        self._uploadFile(
            'File too large',
            folder,
            size=4096,
            validationError='Upload would exceed file storage quota')
        # But a 2 kb file will succeed
        file = self._uploadFile('Second upload', folder, size=2048)
        # And a second 2 kb file will fail
        self._uploadFile(
            'File too large',
            folder,
            size=2048,
            validationError='Upload would exceed file storage quota')
        # If we start uploading two files, only one should complete
        file1kwargs = self._uploadFile('First partial',
                                       folder,
                                       size=768,
                                       partial=True)
        file2kwargs = self._uploadFile('Second partial',
                                       folder,
                                       size=768,
                                       partial=True)
        resp = self.multipartRequest(**file1kwargs)
        self.assertStatusOk(resp)
        try:
            resp = self.multipartRequest(**file2kwargs)
            self.assertStatus(resp, 400)
        except AssertionError as exc:
            self.assertTrue('Upload exceeded' in exc.args[0])
        # Shrink the quota to smaller than all of our files.  Replacing an
        # existing file should still work, though
        self._setPolicy({'fileSizeQuota': 2048}, model, resource, user)
        self._uploadFile('Second upload', file, 'file', size=1536)
        # Now test again using default quotas.  We have 1024+1536+768 = 3328
        # bytes currently uploaded
        self._setPolicy({'useQuotaDefault': True}, model, resource, user)
        # Upload should now be unlimited, so anything will work
        self._uploadFile('Fourth upload', folder, size=1792)
        # Set a policy limiting things to 8 kb, then an additional 4 kb file
        # should fail
        self._setQuotaDefault(model, 8192)
        self._uploadFile(
            'File too large',
            folder,
            size=4096,
            validationError='Upload would exceed file storage quota')
        # But a 2 kb file will succeed
        file = self._uploadFile('Fifth upload', folder, size=2048)
        # And a second 2 kb file will fail
        self._uploadFile(
            'File too large',
            folder,
            size=2048,
            validationError='Upload would exceed file storage quota')
        # Set a policy with a large quota to test using NumberLong in the
        # mongo settings.
        self._setQuotaDefault(model, 5 * 1024**3)
        # A small file should now upload
        file = self._uploadFile('Six upload', folder, size=2048)
        # But a huge one will fail
        self._uploadFile(
            'File too large',
            folder,
            size=6 * 1024**3,
            validationError='Upload would exceed file storage quota')