コード例 #1
0
 def test_verify_nonprivileged_user_cannot_change_other_fields(self):
     '''
     Verify that a non-privileged user cannot change their account aside from the password.
     '''
     payload={'format': 'json' }
     response=self.client.get(self.api_user_url, params=payload)
     
     # Create the user
     username, password=self.getUsernamePassword()
     response=self._create_user(username, password)
     user_uri=response.headers['location']
     
     # Get a login session
     client=NMTKClient(self.site_url)
     response=client.login(username, password)
     
     user_data=client.get(user_uri).json()
     user_data['username']='******'
     # Just in case
     self.delusers.append('test_new_username')
     response=client.put(user_uri, data=json.dumps(user_data))
     logger.debug(response.text)
     self.assertEqual(response.status_code, 401,
                      'Response to change username should be 400, not %s' %
                      (response.status_code,))
コード例 #2
0
 def test_verify_nonprivileged_user_cannot_create_users(self):
     '''
     Verify that a non-privileged user cannot create user accounts
     '''
     payload={'format': 'json' }
     response=self.client.get(self.api_user_url, params=payload)
     
     # Create the user
     username, password=self.getUsernamePassword()
     response=self._create_user(username, password)
     self.assertEqual(201, response.status_code,
                      'Expected status code of 201, not %s' % 
                      (response.status_code))
     user_uri=response.headers['location']
     
     # Try to create a user
     client=NMTKClient(self.site_url)
     response=client.login(username, password)
     
     data={'username': '******' % username,
           'password': password}
     
     response=client.post(self.api_user_url,
                           data=json.dumps(data),
                           headers={'Content-Type': 'application/json',})
     logger.debug('Response from create user request was %s', 
                  response.status_code)
     self.assertEqual(401, response.status_code)
     
     response=self.client.get(self.api_user_url, params=payload)
     for v in response.json()['objects']:
         self.assertFalse(v['username'] == data['username'],
                          'User %s was created, but should not have been' %
                          data['username']) 
コード例 #3
0
    def test_verify_nonprivileged_user_cannot_change_other_fields(self):
        '''
        Verify that a non-privileged user cannot change their account aside from the password.
        '''
        payload = {'format': 'json'}
        response = self.client.get(self.api_user_url, params=payload)

        # Create the user
        username, password = self.getUsernamePassword()
        response = self._create_user(username, password)
        user_uri = response.headers['location']

        # Get a login session
        client = NMTKClient(self.site_url)
        response = client.login(username, password)

        user_data = client.get(user_uri).json()
        user_data['username'] = '******'
        # Just in case
        self.delusers.append('test_new_username')
        response = client.put(user_uri, data=json.dumps(user_data))
        logger.debug(response.text)
        self.assertEqual(
            response.status_code, 401,
            'Response to change username should be 400, not %s' %
            (response.status_code, ))
コード例 #4
0
 def test_login_verify(self):
     '''
     Verify we can successfully log into the site.
     Tests that the client works properly, sets the right CSRF headers,
     and that the server accepts a login properly.
     '''
     client=NMTKClient(self.site_url)
     result=client.login(self.username, self.password)
     # Verify that we logged in successfully by checking the status code
     self.assertEqual(result.status_code, 302)
コード例 #5
0
 def test_login_verify(self):
     '''
     Verify we can successfully log into the site.
     Tests that the client works properly, sets the right CSRF headers,
     and that the server accepts a login properly.
     '''
     client = NMTKClient(self.site_url)
     result = client.login(self.username, self.password)
     # Verify that we logged in successfully by checking the status code
     self.assertEqual(result.status_code, 302)
コード例 #6
0
    def setUp(self):
        self.settings_command = os.path.join(nmtk_path,
                                             'NMTK_apps/manage.py')
        self.delusers = []
        config = self._getSiteConfig()

        self.support_files = os.path.join(nmtk_path, 'tests/support_files')
        self.site_url = config['site_url']
        self.username = config['username']
        self.password = config['password']
        self.verify_ssl = config['verify_ssl']
        self.client = NMTKClient(self.site_url,
                                 verify_ssl=self.verify_ssl)
        self.client.login(self.username, self.password)
        self.api_user_url = self.client.getURL('api', 'user/')
        self.api_file_url = self.client.getURL('api', 'datafile/')
コード例 #7
0
 def test_setup_job(self):
     '''
     Upload and supply a data file for some jobs, then verify the form comes back.
     '''
     username, password=self.getUsernamePassword()
     user_uri=self._create_user(username,password)
     client=NMTKClient(self.site_url)
     response=client.login(username=username,
                           password=password)
     filename=self.get_support_file('test1.geojson')
     test_file=client.uploadData(filename, 
                                 description='Test data file (MSP)')
     logger.debug('URI of test file is %s', test_file)
     
     tool_url=client.getURL('api','tool/')
     job_url=client.getURL('api','job/')
     response=client.get(tool_url, params={'format': 'json'})
     tools=response.json()['objects']
     tool_uri_list=[]
     # Get a list of all the Tool Resource URIs for Minnesota models,
     # since the test1.geojson file is a MN model-specific data file.
     for tool in tools:
         if 'minnesota' in tool['name'].lower():
             tool_uri_list.append(tool['resource_uri'])
     job_uri_list=[]
     for uri in tool_uri_list:
         data={'tool': client.neuter_url(uri),
               'data_file': client.neuter_url(test_file)}
         response=client.post(job_url, 
                              data=json.dumps(data),
                              headers={'Content-Type': 'application/json',})
         self.assertEqual(response.status_code, 201,
                          ('Expected job to be created - ' +
                           'got back %s instead') % (
                          response.status_code))
         logger.debug('Created new job entry with URI %s', 
                      response.headers['location'])
         job_uri_list.append(response.headers['location'])
     for uri in job_uri_list:
         response=client.get(uri, params={'format': 'json'})
         data=response.json()
         self.assertTrue(len(json.dumps(data.get('form',''))) > 10, 
                         'Expected the form to appear in' +
                         'the output JSON (got %s)' % (response.text,))
コード例 #8
0
 def test_file_upload_with_description(self):
     '''
     Verify that files can be uploaded with a description
     '''
     username, password=self.getUsernamePassword()
     user_uri=self._create_user(username,password)
     client=NMTKClient(self.site_url)
     client.login(username=username,
                  password=password)
     description='Test upload file description'
     response=self.upload_file(client, 
                               'test1.geojson',
                               description)
     logger.debug('Location for uploaded file is %s', 
                  response.headers['location'])
     loc=response.headers['location']
     
     response=client.get(loc, params={'format': 'json'})
     logger.debug(response.text)
     self.assertEqual(response.json()['description'],description,
                      'Expected uploaded description to be present')
コード例 #9
0
    def test_basic_different_srid_shapefile_upload(self):
        '''
        Test the upload and processing of a non standard shapefile (different EPSG)
        '''
        json_file=open(self.get_support_file('odd_srid_shapefile.zip'),'r')
        username, password=self.getUsernamePassword()
        user_uri=self._create_user(username,password)
        client=NMTKClient(self.site_url)
        client.login(username=username,
                     password=password)
        files=[('file', ('shapefile_odd_srid.zip', json_file, 'application/zip')),]
        response=client.post(self.api_file_url, files=files)
        logger.debug('Response from POST was %s', response)
        self.assertEqual(response.status_code, 201)
        data_file_url=response.headers['location']
        logger.debug('Response was %s', response.status_code)
        logger.debug('Location of data file is %s', data_file_url)
        
        end=time.time() + self.timeout # 5 minutes for processing
        while time.time() < end :
            response=client.get(data_file_url,
                                params={'format': 'json'})
            logger.debug('Response is %s', response.json())

            if response.json()['status'] == 'Import Complete':
                break
            time.sleep(1)
        self.assertEqual(response.json()['status'],
                         'Import Complete',
                         'Expected import to successfully complete within %s seconds' % (self.timeout,))
コード例 #10
0
ファイル: test_review_tools.py プロジェクト: jrawbits/nmtk-1
 def test_list_tools(self):
     '''
     Verify that any user (even without login) can retrieve a list of tools.
     '''
     username, password = self.getUsernamePassword()
     user_uri = self._create_user(username, password)
     client = NMTKClient(self.site_url)
     tool_url = client.getURL('api', 'tool/')
     logger.debug('Attempting to get tool list (%s) as not-logged-in user',
                  tool_url)
     response = client.get(tool_url, params={'format': 'json'})
     self.assertEqual(200, response.status_code,
                      'expected 200, not %s' % (response.status_code,))
     response = client.login(username=username,
                             password=password)
     response = client.get(tool_url, params={'format': 'json'})
     self.assertEqual(200, response.status_code,
                      'expected 200 (when logged in), not %s' %
                      (response.status_code,))
     jsdata = response.json()
     self.assertEqual(min(jsdata['meta']['total_count'],
                          jsdata['meta']['limit']), len(jsdata['objects']),
                      'Expected the number of objects returned to match the purported count!')
コード例 #11
0
ファイル: NMTKTestCase.py プロジェクト: jrawbits/nmtk-1
    def setUp(self):
        self.settings_command = os.path.join(nmtk_path,
                                             'NMTK_apps/manage.py')
        self.delusers = []
        config = self._getSiteConfig()

        self.support_files = os.path.join(nmtk_path, 'tests/support_files')
        self.site_url = config['site_url']
        self.username = config['username']
        self.password = config['password']
        self.client = NMTKClient(self.site_url)
        self.client.login(self.username, self.password)
        self.api_user_url = self.client.getURL('api', 'user/')
        self.api_file_url = self.client.getURL('api', 'datafile/')
コード例 #12
0
    def test_verify_nonprivileged_user_cannot_create_users(self):
        '''
        Verify that a non-privileged user cannot create user accounts
        '''
        payload = {'format': 'json'}
        response = self.client.get(self.api_user_url, params=payload)

        # Create the user
        username, password = self.getUsernamePassword()
        response = self._create_user(username, password)
        self.assertEqual(
            201, response.status_code,
            'Expected status code of 201, not %s' % (response.status_code))
        user_uri = response.headers['location']

        # Try to create a user
        client = NMTKClient(self.site_url)
        response = client.login(username, password)

        data = {'username': '******' % username, 'password': password}

        response = client.post(self.api_user_url,
                               data=json.dumps(data),
                               headers={
                                   'Content-Type': 'application/json',
                               })
        logger.debug('Response from create user request was %s',
                     response.status_code)
        self.assertEqual(401, response.status_code)

        response = self.client.get(self.api_user_url, params=payload)
        for v in response.json()['objects']:
            self.assertFalse(
                v['username'] == data['username'],
                'User %s was created, but should not have been' %
                data['username'])
コード例 #13
0
 def test_file_upload_with_srid(self):
     '''
     Verify that files can be uploaded with an SRID
     '''
     username, password=self.getUsernamePassword()
     user_uri=self._create_user(username,password)
     client=NMTKClient(self.site_url)
     client.login(username=username,
                  password=password)
     description='Test upload file description'
     srid=3857
     response=self.upload_file(client, 
                               'test1.geojson',
                               description, payload={'srid': srid})
     logger.debug('Location for uploaded file is %s', 
                  response.headers['location'])
     data_file_url=response.headers['location']
     
     response=client.get(data_file_url, params={'format': 'json'})
     logger.debug(response.text)
     json_data=response.json()
     self.assertEqual(json_data['description'],description,
                      'Expected uploaded description to be present')
     self.assertEqual(json_data['srid'], srid,
                      'Expected SRID to be %s' % (srid,))
     # Verify the processing completes
     end=time.time() + 60*2 # 2 minutes for processing
     while time.time() < end :
         response=client.get(data_file_url,
                             params={'format': 'json'})
         logger.debug('Response was %s', response.text)
         if response.json()['status'] == 'Import Complete':
             break
         time.sleep(1)
     self.assertEqual(response.json()['status'],
                      'Import Complete',
                      'Expected import to successfully complete within 120 seconds')
     
     # Get the data again and make sure the SRID provided was used, and 
     # preserved.
     response=client.get(data_file_url, params={'format': 'json'})
     json_data=response.json()
     logger.debug('Response was %s', json_data)
     self.assertEqual(json_data['description'],description,
                      'Expected uploaded description to be present')
     self.assertEqual(json_data['srid'], srid,
                      'Expected SRID to be %s' % (srid,))
コード例 #14
0
    def test_logout_verify(self):
        '''
        Verify that we can log out successfully.
        Verifies that logout functionality works, and that the server
        properly invalidates the session when logout is requested.  Verify
        that the correct redirect URL is provided for login after a user has
        logged out.
        '''

        client = NMTKClient(self.site_url)
        test_url = '%s%s' % (client.getURL('api'), 'job/')
        result = client.login(self.username, self.password)
        self.assertEqual(result.status_code, 302)
        result = client.get(test_url, params={'format': 'json'})
        self.assertEqual(result.status_code, 200)
        result = client.logout()
        self.assertEqual(result.status_code, 302)
        login_url = client.getURL('login')[:-1]

        result = client.get(test_url, params={'format': 'json'})
        self.assertEqual(result.status_code, 401)
コード例 #15
0
ファイル: test_file_upload.py プロジェクト: jrawbits/nmtk-1
    def test_file_upload_with_srid(self):
        '''
        Verify that files can be uploaded with an SRID
        '''
        username, password = self.getUsernamePassword()
        user_uri = self._create_user(username, password)
        client = NMTKClient(self.site_url)
        client.login(username=username,
                     password=password)
        description = 'Test upload file description'
        srid = 3857
        response = self.upload_file(client,
                                    'test1.geojson',
                                    description, payload={'srid': srid})
        logger.debug('Location for uploaded file is %s',
                     response.headers['location'])
        data_file_url = response.headers['location']

        response = client.get(data_file_url, params={'format': 'json'})
        logger.debug(response.text)
        json_data = response.json()
        self.assertEqual(json_data['description'], description,
                         'Expected uploaded description to be present')
        self.assertEqual(json_data['srid'], srid,
                         'Expected SRID to be %s' % (srid,))
        # Verify the processing completes
        end = time.time() + 60 * 2  # 2 minutes for processing
        while time.time() < end:
            response = client.get(data_file_url,
                                  params={'format': 'json'})
            logger.debug('Response was %s', response.text)
            if response.json()['status'] == 'Import Complete':
                break
            time.sleep(1)
        self.assertEqual(
            response.json()['status'],
            'Import Complete',
            'Expected import to successfully complete within 120 seconds')

        # Get the data again and make sure the SRID provided was used, and
        # preserved.
        response = client.get(data_file_url, params={'format': 'json'})
        json_data = response.json()
        logger.debug('Response was %s', json_data)
        self.assertEqual(json_data['description'], description,
                         'Expected uploaded description to be present')
        self.assertEqual(json_data['srid'], srid,
                         'Expected SRID to be %s' % (srid,))
コード例 #16
0
    def test_logout_verify(self):
        '''
        Verify that we can log out successfully.
        Verifies that logout functionality works, and that the server
        properly invalidates the session when logout is requested.  Verify
        that the correct redirect URL is provided for login after a user has
        logged out.
        '''

        client = NMTKClient(self.site_url)
        test_url = '%s%s' % (client.getURL('api'),
                             'job/')
        result = client.login(self.username, self.password)
        self.assertEqual(result.status_code, 302)
        result = client.get(test_url, params={'format': 'json'})
        self.assertEqual(result.status_code, 200)
        result = client.logout()
        self.assertEqual(result.status_code, 302)
        login_url = client.getURL('login')[:-1]

        result = client.get(test_url, params={'format': 'json'})
        self.assertEqual(result.status_code, 401)
コード例 #17
0
ファイル: test_review_tools.py プロジェクト: nmtkpbic/nmtk
 def test_list_tools(self):
     '''
     Verify that any user (even without login) can retrieve a list of tools.
     '''
     username, password = self.getUsernamePassword()
     user_uri = self._create_user(username, password)
     client = NMTKClient(self.site_url)
     tool_url = client.getURL('api', 'tool/')
     logger.debug('Attempting to get tool list (%s) as not-logged-in user',
                  tool_url)
     response = client.get(tool_url, params={'format': 'json'})
     self.assertEqual(200, response.status_code,
                      'expected 200, not %s' % (response.status_code, ))
     response = client.login(username=username, password=password)
     response = client.get(tool_url, params={'format': 'json'})
     self.assertEqual(
         200, response.status_code,
         'expected 200 (when logged in), not %s' % (response.status_code, ))
     jsdata = response.json()
     self.assertEqual(
         min(jsdata['meta']['total_count'], jsdata['meta']['limit']),
         len(jsdata['objects']),
         'Expected the number of objects returned to match the purported count!'
     )
コード例 #18
0
    def test_submit_job(self):
        '''
        Verify that we can properly submit a job (form) via the API and \
get back the (eventual) results and status of the running job.  Also ensure other \
users cannot download results.
        '''
        username, password=self.getUsernamePassword()
        user_uri=self._create_user(username,password)
        client=NMTKClient(self.site_url)
        response=client.login(username=username,
                              password=password)
        filename=self.get_support_file('test1.geojson')
        test_file=client.uploadData(filename, 
                                    description='Test data file (MSP)')
        logger.debug('URI of test file is %s', test_file)
        
        tool_url=client.getURL('api','tool/')
        job_url=client.getURL('api','job/')
        response=client.get(tool_url, params={'format': 'json'})
        tools=response.json()['objects']

        # Get a list of all the Tool Resource URIs for Minnesota models,
        # since the test1.geojson file is a MN model-specific data file.
        for tool in tools:
            if 'umn' in tool['name'].lower():
                tool_uri=tool['resource_uri']
                break
        data={'tool': client.neuter_url(tool_uri),
              'description': 'Test job for testing by the automated test!'}
        
        response=client.post(job_url, 
                             data=json.dumps(data),
                             headers={'Content-Type': 'application/json',})
        #logger.debug('Result from post was %s', response.text)
        self.assertEqual(response.status_code, 201,
                         ('Expected job to be created - ' +
                          'got back %s instead') % (response.status_code,))
        job_uri=response.headers['location']
        
        # Now we have a job, let's get the form, generate the response, and
        # submit it back to the user.
        payload={ "config": { "coefficients": {"Arterial_coeff": { "type": "number",
                                                                   "value": 391.8 },
                                               "BusRoute_coeff": { "type": "number",
                                                                   "value": 100.3 },
                                               "CBDdist_km_coeff": { "type": "number",
                                                                     "value": -40.3 },
                                               "Collector_coeff": { "type": "number",
                                                                    "value": 611.1 },
                                               "Crime_coeff": { "type": "number",
                                                                "value": 2.9 },
                                               "EmployAccess_coeff": { "type": "number",
                                                                       "value": 0 },
                                               "LUMix_coeff": { "type": "number",
                                                                "value": -919.9 },
                                               "MedHHInc_coeff": { "type": "number",
                                                                   "value": 2.1 },
                                               "OffstreetTrail_coeff": { "type": "number",
                                                                         "value": 253.8  },
                                               "PDperkm2_coeff": { "type": "number",
                                                                   "value": -0.035  },
                                               "PctU5_O65_coeff": { "type": "number",
                                                                    "value": 32.5 },
                                               "Pctnonwhite_coeff": { "type": "number",
                                                                      "value": -29.8 },
                                               "Pctw4ormore_coeff": { "type": "number",
                                                                      "value": 371.4  },
                                               "Precip_coeff": { "type": "number",
                                                                 "value": -127.8 },
                                               "Principal_coeff": { "type": "number",
                                                                    "value": 66.4 },
                                               "Tmax_coeff": { "type": "number",
                                                               "value": -26 },
                                               "WatDist_km_coeff": { "type": "number",
                                                                     "value": -21.6 },
                                               "Year_coeff": { "type": "number",
                                                               "value": -5.9 },
                                               "constant": { "type": "number",
                                                             "value": 788.6 }
                                               },
                             "data": { "Arterial": { "type": "property",
                                                     "value": "Arterial" },
                                      "BusRoute": { "type": "property",
                                                    "value": "BusRoute" },
                                      "CBDdist_km": { "type": "property",
                                                      "value": "CBDdist_km" },
                                      "Collector": { "type": "property",
                                                     "value": "Collector" },
                                      "Crime": { "type": "property",
                                                 "value": "Crime" },
                                      "EmployAccess": { "type": "property",
                                                        "value": "EmployAccess" },
                                      "LUMix": { "type": "property",
                                                 "value": "LUMix" },
                                      "MedHHInc": { "type": "property",
                                                    "value": "MedHHInc" },
                                      "OffstreetTrail": { "type": "property",
                                                          "value": "OffstreetTrail" },
                                      "PDperkm2": { "type": "property",
                                                    "value": "PDperkm2" },
                                      "PctU5_O65": { "type": "property",
                                                     "value": "PctU5_O65" },
                                      "Pctnonwhite": { "type": "property",
                                                       "value": "Pctnonwhite" },
                                      "Pctw4ormore": { "type": "property",
                                                       "value": "Pctw4ormore" },
                                      "Principal": { "type": "property",
                                                     "value": "Principal" },
                                      "WatDist_km": { "type": "property",
                                                     "value": "WatDist_km" }
                                      },
                             "results": { "result": { "type": "string",
                                                      "value": "ped12ols" }
                                         }
                             },
                 "file_config": {
                                 "data": test_file
                                 }
                 }
        data=client.get(job_uri,
                        params={'format': 'json'}).json()
        data.update(payload)
        job_id=data['id']

        response=client.put(job_uri, 
                            headers={'Content-Type': 'application/json',},
                            data=json.dumps(data))
        logger.debug('Response from job update was %s', response.text)
        self.assertTrue(response.status_code in (204,202),
                         'Expected a return code of 204/202 with valid ' + 
                         'data provided got (%s)' % (response.status_code))
        
        # Now check the status to wait for completion
        timeout=time.time() + 120
        status_url=client.getURL('api','job_status/')
        params={'job': job_id,
                'format': 'json',
                'limit': 1 }
        steps=['Parameter & data file validation complete.','COMPLETE']
        prev_response=''
        while time.time() < timeout:
            response=client.get(status_url, params=params)
            self.assertEqual(response.status_code, 200,
                             'Expected to get valid response back')
            if len(response.text):
                json_data=response.json()
                if prev_response <> response.text:
                    logger.debug('Reponse changed to %s', response.text)
                prev_response=response.text
                if json_data['meta']['total_count']:
                    if json_data['objects'][0]['message'] in steps:
                        steps.remove(json_data['objects'][0]['message'])
                    if json_data['objects'][0]['message']=='COMPLETE':
                        break
            time.sleep(.1)
        self.assertEqual(len(steps),0, 
                         'Did not get expected message(s) %s' % (steps,))
        
        response=client.get(job_uri, params={'format': 'json'})
        json_response=response.json()
        self.assertTrue(json_response['status'] in ('Post-processing results', 'Complete'),
                         'Expected a status of Complete, not %s' % (json_response['status']))
        
        timeout=time.time() + 120
        while time.time() < timeout:
            if json_response['status'] == 'Complete':
                break
            response=client.get(job_uri, params={'format': 'json'})
            json_response=response.json()
            time.sleep(.1)
        else:
            self.fail('Expected status to be complete after 120s timeout, not %s' % (json_response['status']))
        results_uri=None
        for row in json_response['results_files']:
            if row['primary']:
                logger.debug("Primary results were %s", row)
                results_uri=client.getURL(path=row['datafile'])
        if not results_uri:
            self.fail('Expected to get back a primary result, none found in %s' % (json_response,))
        # Try to see if another user can download this job or results..
        username2, password2=self.getUsernamePassword()
        user_uri=self._create_user(username2,password2)
        client2=NMTKClient(self.site_url)
        client2.login(username=username2,
                      password=password2)
        response=client2.get(job_uri, params={'format': 'json'})
        self.assertEqual(response.status_code, 401,
                         ('Expected 401 forbidden when ' +
                          'another user tried to get job info (not %s)') % (response.status_code,))
        response=client2.get(results_uri, 
                             params={'format': 'json'})
        self.assertEqual(response.status_code, 401,
                         ('Expected 401 forbidden when ' +
                          'another user tried to get result (not %s)') % (response.status_code,))
        
        response=client.get(results_uri, 
                            params={'format': 'json'})
        self.assertEqual(response.status_code, 200,
                         'Status code expected was 200, not %s' % (response.status_code,))
        logger.debug('Header is %s', response.headers)

        data=json.loads(response.content)
コード例 #19
0
    def test_create_delete_user(self):
        '''
        Verify that we can create a user via the API, and delete a user via the API
        In this case we will also validate that users, once deleted, are 
        effectively neutered via the UI.  The same is true for a logged in user
        whose account is deleted while the user is logged in.
        '''
        payload = {'format': 'json', 'limit': 999, 'all': True}
        response = self.client.get(self.api_user_url, params=payload)
        user_count = response.json()['meta']['total_count']
        # Create the user
        username, password = self.getUsernamePassword()
        response = self._create_user(username, password)
        self.assertEqual(
            201, response.status_code,
            'Expected status code of 201, not %s' % (response.status_code))
        user_uri = response.headers['location']
        response = self.client.get(user_uri, params=payload)
        self.assertEqual(
            response.status_code, 200,
            'Expected to get user data, not %s (%s)' %
            (response.status_code, response.text))
        logger.debug('Response was %s', response.json())
        # Get a list of users, verifying that user is there
        response = self.client.get(self.api_user_url, params=payload)

        json_data = response.json()
        # Verify we have one more user than before
        self.assertEqual(
            user_count + 1, json_data['meta']['total_count'],
            'Final count of users is %s, expected %s' %
            (json_data['meta']['total_count'], user_count + 1))
        # Verify that the user we created exists
        usernames = [rec['username'] for rec in json_data['objects']]
        self.assertTrue(
            username in usernames,
            'Username %s not found in %s' % (username, ','.join(usernames)))

        # Verify we can get the user via a query
        payload2 = payload.copy()
        payload2['username'] = username
        response = self.client.get(self.api_user_url, params=payload2)
        json_data = response.json()
        logger.debug('Response was %s', response.text)
        self.assertEqual(
            1, json_data['meta']['total_count'],
            'Retrieve record for ONLY %s, got %s records back' %
            (username, json_data['meta']['total_count']))

        # Verify that the user we created exists (just copy the check from above,
        # because I am lazy - and this works the same)
        usernames = [rec['username'] for rec in json_data['objects']]
        self.assertTrue(
            username in usernames,
            'Username %s not found in %s' % (username, ','.join(usernames)))

        # MAke sure that meta wasn't lying, and we really only got one record back.
        self.assertEqual(len(usernames),
                         1,
                         msg='More than one user returned from query')

        # Verify we can login as the newly created user.
        client = NMTKClient(self.site_url)
        response = client.login(username, password)
        logger.debug('Response from login was %s', response.status_code)
        self.assertEqual(response.status_code, 302,
                         'Login did not produce expected redirect')
        self.assertTrue(len(response.headers.get('location')),
                        'Redirect location header expected, not provided')
        response = client.get(client.getURL(path=''), allow_redirects=False)
        self.assertEqual(200, response.status_code,
                         'Unexpected redirect retrieving protected URI')

        # Delete the user we just created
        response = self._delete_user(user_uri)
        self.assertEqual(204, response.status_code)

        # Try to access a protected URL
        response = client.get(client.getURL(path=self.protected_url),
                              allow_redirects=False)
        self.assertEqual(
            302, response.status_code,
            'Deleted user should not be able to access a' + ' protected URI')

        # Try to login again as the disabled user:
        client = NMTKClient(self.site_url)
        response = client.login(username, password)
        self.assertEqual(200, response.status_code,
                         'Login for deleted user should fail')

        response = client.get(client.getURL(path=self.protected_url),
                              allow_redirects=False)
        self.assertEqual(
            302, response.status_code,
            'Deleted user should not be able to access a' + ' protected URI')
コード例 #20
0
    def test_setup_job(self):
        '''
        Upload and supply a data file for some jobs, then verify the form comes back.
        '''
        username, password = self.getUsernamePassword()
        user_uri = self._create_user(username, password)
        client = NMTKClient(self.site_url)
        response = client.login(username=username, password=password)
        filename = self.get_support_file('test1.geojson')
        test_file = client.uploadData(filename,
                                      description='Test data file (MSP)')
        logger.debug('URI of test file is %s', test_file)

        tool_url = client.getURL('api', 'tool/')
        job_url = client.getURL('api', 'job/')
        response = client.get(tool_url, params={'format': 'json'})
        tools = response.json()['objects']
        tool_uri_list = []
        # Get a list of all the Tool Resource URIs for Minnesota models,
        # since the test1.geojson file is a MN model-specific data file.
        for tool in tools:
            if 'minnesota' in tool['name'].lower():
                tool_uri_list.append(tool['resource_uri'])
        job_uri_list = []
        for uri in tool_uri_list:
            data = {
                'tool': client.neuter_url(uri),
                'data_file': client.neuter_url(test_file)
            }
            response = client.post(job_url,
                                   data=json.dumps(data),
                                   headers={
                                       'Content-Type': 'application/json',
                                   })
            self.assertEqual(
                response.status_code, 201,
                ('Expected job to be created - ' + 'got back %s instead') %
                (response.status_code))
            logger.debug('Created new job entry with URI %s',
                         response.headers['location'])
            job_uri_list.append(response.headers['location'])
        for uri in job_uri_list:
            response = client.get(uri, params={'format': 'json'})
            data = response.json()
            self.assertTrue(
                len(json.dumps(data.get('form', ''))) > 10,
                'Expected the form to appear in' + 'the output JSON (got %s)' %
                (response.text, ))
コード例 #21
0
    def test_user_change_password(self):
        '''
        Verify that password change functionality functions as designed.
        '''
        payload = {'format': 'json'}
        response = self.client.get(self.api_user_url, params=payload)

        # Create the user
        username, password = self.getUsernamePassword()
        response = self._create_user(username, password)
        user_url = response.headers['location']
        # Create the user
        username2, password2 = self.getUsernamePassword()
        response = self._create_user(username2, password2)
        user2_url = response.headers['location']

        client = NMTKClient(self.site_url)
        response = client.login(username, password)

        client2 = NMTKClient(self.site_url)
        response = client2.login(username2, password2)

        client_data = client.get(user_url).json()
        client2_data = client2.get(user2_url).json()

        # user changes his own password, but fails to supply old password
        client_data['password'] = '******' % (password, )
        response = client.put(user_url, data=json.dumps(client_data))
        self.assertEqual(response.status_code, 400,
                         'Without old password password change should fail')

        # login with new password
        client_a = NMTKClient(self.site_url)
        response = client_a.login(username, client_data['password'])
        self.assertEqual(
            response.status_code, 200,
            'Redirect not expected after unsuccessful login (pw not changed)')

        # user changes his own password, but supplys bad old password
        client_data['current_password'] = '******' % (password, )
        response = client.put(user_url, data=json.dumps(client_data))
        self.assertEqual(response.status_code, 400,
                         'Without old password password change should fail')

        # login with new password
        client_a = NMTKClient(self.site_url)
        response = client_a.login(username, client_data['password'])
        self.assertEqual(
            response.status_code, 200,
            'Redirect not expected after unsuccessful login (pw not changed)')

        # user changes his own password, but fails to supply old password
        client_data['current_password'] = password
        client.put(user_url, data=json.dumps(client_data))

        # login with new password
        client_a = NMTKClient(self.site_url)
        response = client_a.login(username, client_data['password'])
        self.assertEqual(response.status_code, 302,
                         'Redirect expected after successful login')

        # Verify old password no longer works
        response = client_a.login(username, password)
        self.assertEqual(
            response.status_code, 200,
            'Redirect not expected after login ' + 'attempt with old password')

        # User tries to change another users password
        client2_data['password'] = password
        response = client.put(user2_url,
                              data=json.dumps(client2_data),
                              headers={
                                  'Content-Type': 'application/json',
                              })
        self.assertEqual(
            401, response.status_code,
            'Expected to get a 401 (Unauthorized) when a ' +
            'non-superuser tries to change another users password')

        # Verify old password still works
        response = client_a.login(username2, password2)
        self.assertEqual(
            response.status_code, 302, 'Redirect expected after login ' +
            'attempt with original password')

        # Superuser tries to change user password.
        logger.debug(
            self.client.get(self.api_user_url, params={
                'format': 'json'
            }).json())
        logger.debug('Client data is %s', client2_data)
        response = self.client.put(user2_url,
                                   data=json.dumps(client2_data),
                                   headers={
                                       'Content-Type': 'application/json',
                                   })
        logger.debug('Response from put was %s: %s', response.status_code,
                     response.text)
        self.assertTrue(
            response.status_code in (202, 204),
            'Expected to get a 204 when a ' +
            'superuser tries to change another users password')

        # Verify password change worked
        client2_a = NMTKClient(self.site_url)
        response = client2_a.login(username2, password)
        self.assertEqual(response.status_code, 302,
                         'Redirect expected after successful login')

        # Verify old password no longer works
        response = client2_a.login(username2, password2)
        self.assertEqual(
            response.status_code, 200,
            'Redirect not expected after login ' + 'attempt with old password')
コード例 #22
0
    def test_prevent_user_from_using_other_user_data(self):
        '''
        Verify that one user can neither access, nor submit jobs, with another users data
        '''
        username, password = self.getUsernamePassword()
        user_uri = self._create_user(username, password)
        username2, password2 = self.getUsernamePassword()
        user_uri = self._create_user(username2, password2)
        client = NMTKClient(self.site_url)
        client.login(username=username, password=password)
        client2 = NMTKClient(self.site_url)
        client2.login(username=username2, password=password2)
        filename = self.get_support_file('test1.geojson')
        test_file = client.uploadData(filename,
                                      description='Test configuration file')
        # Just try to access the other users file
        response = client2.get(test_file, params={'format': 'json'})
        logger.debug('Response when getting other users file was %s',
                     response.status_code)
        self.assertEqual(response.status_code, 401,
                         'Expected a 401, got a %s' % (response.status_code, ))
        # Try to create a job with the other users file
        job_url = client.getURL('api', 'job/')
        tool_url = client.getURL('api', 'tool/')

        response = client.get(tool_url, params={'format': 'json'})
        tools = response.json()['objects']
        # Get a list of all the Tool Resource URIs for Minnesota models,
        # since the test1.geojson file is a MN model-specific data file.
        for tool in tools:
            if 'umn' in tool['name'].lower():
                tool_uri = tool['resource_uri']
                break
        data = {
            'tool': client.neuter_url(tool_uri),
            'description': 'how now brown cow'
        }
        logger.debug(
            'Verifying that user A cannot create a job with User B data')
        response = client2.post(job_url,
                                data=json.dumps(data),
                                headers={
                                    'Content-Type': 'application/json',
                                })
        logger.debug('Status code was %s', response.status_code)
        logger.debug('Response text was %s', response.text)
コード例 #23
0
    def test_submit_job_other_user_denied_access(self):
        '''
        Verify that once a job is submitted/created, other users cannot access.
        '''
        username, password = self.getUsernamePassword()
        user_uri = self._create_user(username, password)
        client = NMTKClient(self.site_url)
        response = client.login(username=username, password=password)
        username2, password2 = self.getUsernamePassword()
        user_uri2 = self._create_user(username2, password2)
        client2 = NMTKClient(self.site_url)
        client2.login(username=username2, password=password2)
        filename = self.get_support_file('test1.geojson')
        test_file = client.uploadData(filename,
                                      description='Test data file (MSP)')
        logger.debug('URI of test file is %s', test_file)

        tool_url = client.getURL('api', 'tool/')
        job_url = client.getURL('api', 'job/')
        response = client.get(tool_url, params={'format': 'json'})
        tools = response.json()['objects']
        # Get a list of all the Tool Resource URIs for Minnesota models,
        # since the test1.geojson file is a MN model-specific data file.
        for tool in tools:
            if 'umn' in tool['name'].lower():
                tool_uri = tool['resource_uri']
                break
        data = {
            'tool': client.neuter_url(tool_uri),
            'description': 'how now brown cow'
        }

        response = client.post(job_url,
                               data=json.dumps(data),
                               headers={
                                   'Content-Type': 'application/json',
                               })
        self.assertEqual(
            response.status_code, 201,
            ('Expected job to be created - ' + 'got back %s instead') %
            (response.status_code, ))
        job_uri = response.headers['location']
        # Now we have a job, let's get the form, generate the response, and
        # submit it back to the user.
        response = client2.get(job_uri, params={'format': 'json'})
        self.assertEqual(
            response.status_code, 401,
            'Expected client2 to get a 401, not %s' % (response.status_code, ))
コード例 #24
0
class NMTKTestCase(unittest.TestCase):

    def _id_generator(self, size=6,
                      chars=(string.ascii_lowercase +
                             string.ascii_uppercase +
                             string.digits)):
        return ''.join(random.choice(chars) for x in range(size))

    def getUsernamePassword(self):
        return (self._id_generator(), self._id_generator())

    def getClient(self):
        return NMTKClient(self.site_url,
                          verify_ssl=self.verify_ssl)

    def _getSiteConfigDynamic(self):
        try:
            command = ['python',
                       self.settings_command,
                       'create_config']
            proc = subprocess.Popen(command, stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            out, err = proc.communicate()
            config = json.loads(err)
            self.delusers.append(config['username'])
            # Stderr contains the config output.
            return config
        except Exception as e:
            logger.exception('Failed to get dynamic config!')

        return None

    def _getSiteConfigStatic(self):
        config_file = os.path.join(nmtk_path, 'tests/config.json')
        if os.path.exists(config_file):
            try:
                config = json.loads(open(config_file).read())
                return config
            except:
                pass
        return None

    def _getSiteConfig(self):
        config = self._getSiteConfigDynamic() or self._getSiteConfigStatic()
        if config:
            return config
        raise Exception('No valid config found (tried both dynamic and static')

    def getNMTKClient(self, *args, **kwargs):
        return NMTKClient(self.site_url,
                          verify_ssl=self.verify_ssl)

    def setUp(self):
        self.settings_command = os.path.join(nmtk_path,
                                             'NMTK_apps/manage.py')
        self.delusers = []
        config = self._getSiteConfig()

        self.support_files = os.path.join(nmtk_path, 'tests/support_files')
        self.site_url = config['site_url']
        self.username = config['username']
        self.password = config['password']
        self.verify_ssl = config['verify_ssl']
        self.client = NMTKClient(self.site_url,
                                 verify_ssl=self.verify_ssl)
        self.client.login(self.username, self.password)
        self.api_user_url = self.client.getURL('api', 'user/')
        self.api_file_url = self.client.getURL('api', 'datafile/')

    def get_support_file(self, fn):
        return os.path.join(self.support_files, fn)

    def tearDown(self):
        '''
        Use the management purge_users command to purge the users created
        during testing from the database.
        '''
        if self.delusers:
            command = ['python',
                       self.settings_command,
                       'purge_users'] + self.delusers
            with open(os.devnull, "w") as fnull:
                subprocess.call(command, stdout=fnull, stderr=fnull)

    def _create_user(self, *args, **kwargs):
        '''
        A helper method to create a new user, given a password and userid
        '''
        if len(args) == 2:
            kwargs['username'] = args[0]
            kwargs['password'] = args[1]
        for key in ('username', 'password'):
            kwargs.setdefault(key, self._id_generator())

        response = self.client.create_user(**kwargs)
        self.delusers.append(kwargs['username'])
        return response

    def _delete_user(self, url):
        response = self.client.delete(url)
        logger.debug('Deleted %s with status code of %s',
                     url, response.status_code)
        return response
コード例 #25
0
    def test_submit_job(self):
        '''
        Verify that we can properly submit a job (form) via the API and \
get back the (eventual) results and status of the running job.  Also ensure other \
users cannot download results.
        '''
        username, password = self.getUsernamePassword()
        user_uri = self._create_user(username, password)
        client = NMTKClient(self.site_url)
        response = client.login(username=username, password=password)
        filename = self.get_support_file('test1.geojson')
        test_file = client.uploadData(filename,
                                      description='Test data file (MSP)')
        logger.debug('URI of test file is %s', test_file)

        tool_url = client.getURL('api', 'tool/')
        job_url = client.getURL('api', 'job/')
        response = client.get(tool_url, params={'format': 'json'})
        tools = response.json()['objects']

        # Get a list of all the Tool Resource URIs for Minnesota models,
        # since the test1.geojson file is a MN model-specific data file.
        for tool in tools:
            if 'umn' in tool['name'].lower():
                tool_uri = tool['resource_uri']
                break
        data = {
            'tool': client.neuter_url(tool_uri),
            'description': 'Test job for testing by the automated test!'
        }

        response = client.post(job_url,
                               data=json.dumps(data),
                               headers={
                                   'Content-Type': 'application/json',
                               })
        #logger.debug('Result from post was %s', response.text)
        self.assertEqual(
            response.status_code, 201,
            ('Expected job to be created - ' + 'got back %s instead') %
            (response.status_code, ))
        job_uri = response.headers['location']

        # Now we have a job, let's get the form, generate the response, and
        # submit it back to the user.
        payload = {
            "config": {
                "coefficients": {
                    "Arterial_coeff": {
                        "type": "number",
                        "value": 391.8
                    },
                    "BusRoute_coeff": {
                        "type": "number",
                        "value": 100.3
                    },
                    "CBDdist_km_coeff": {
                        "type": "number",
                        "value": -40.3
                    },
                    "Collector_coeff": {
                        "type": "number",
                        "value": 611.1
                    },
                    "Crime_coeff": {
                        "type": "number",
                        "value": 2.9
                    },
                    "EmployAccess_coeff": {
                        "type": "number",
                        "value": 0
                    },
                    "LUMix_coeff": {
                        "type": "number",
                        "value": -919.9
                    },
                    "MedHHInc_coeff": {
                        "type": "number",
                        "value": 2.1
                    },
                    "OffstreetTrail_coeff": {
                        "type": "number",
                        "value": 253.8
                    },
                    "PDperkm2_coeff": {
                        "type": "number",
                        "value": -0.035
                    },
                    "PctU5_O65_coeff": {
                        "type": "number",
                        "value": 32.5
                    },
                    "Pctnonwhite_coeff": {
                        "type": "number",
                        "value": -29.8
                    },
                    "Pctw4ormore_coeff": {
                        "type": "number",
                        "value": 371.4
                    },
                    "Precip_coeff": {
                        "type": "number",
                        "value": -127.8
                    },
                    "Principal_coeff": {
                        "type": "number",
                        "value": 66.4
                    },
                    "Tmax_coeff": {
                        "type": "number",
                        "value": -26
                    },
                    "WatDist_km_coeff": {
                        "type": "number",
                        "value": -21.6
                    },
                    "Year_coeff": {
                        "type": "number",
                        "value": -5.9
                    },
                    "constant": {
                        "type": "number",
                        "value": 788.6
                    }
                },
                "data": {
                    "Arterial": {
                        "type": "property",
                        "value": "Arterial"
                    },
                    "BusRoute": {
                        "type": "property",
                        "value": "BusRoute"
                    },
                    "CBDdist_km": {
                        "type": "property",
                        "value": "CBDdist_km"
                    },
                    "Collector": {
                        "type": "property",
                        "value": "Collector"
                    },
                    "Crime": {
                        "type": "property",
                        "value": "Crime"
                    },
                    "EmployAccess": {
                        "type": "property",
                        "value": "EmployAccess"
                    },
                    "LUMix": {
                        "type": "property",
                        "value": "LUMix"
                    },
                    "MedHHInc": {
                        "type": "property",
                        "value": "MedHHInc"
                    },
                    "OffstreetTrail": {
                        "type": "property",
                        "value": "OffstreetTrail"
                    },
                    "PDperkm2": {
                        "type": "property",
                        "value": "PDperkm2"
                    },
                    "PctU5_O65": {
                        "type": "property",
                        "value": "PctU5_O65"
                    },
                    "Pctnonwhite": {
                        "type": "property",
                        "value": "Pctnonwhite"
                    },
                    "Pctw4ormore": {
                        "type": "property",
                        "value": "Pctw4ormore"
                    },
                    "Principal": {
                        "type": "property",
                        "value": "Principal"
                    },
                    "WatDist_km": {
                        "type": "property",
                        "value": "WatDist_km"
                    }
                },
                "results": {
                    "result": {
                        "type": "string",
                        "value": "ped12ols"
                    }
                }
            },
            "file_config": {
                "data": test_file
            }
        }
        data = client.get(job_uri, params={'format': 'json'}).json()
        data.update(payload)
        job_id = data['id']

        response = client.put(job_uri,
                              headers={
                                  'Content-Type': 'application/json',
                              },
                              data=json.dumps(data))
        logger.debug('Response from job update was %s', response.text)
        self.assertTrue(
            response.status_code in (204, 202),
            'Expected a return code of 204/202 with valid ' +
            'data provided got (%s)' % (response.status_code))

        # Now check the status to wait for completion
        timeout = time.time() + 120
        status_url = client.getURL('api', 'job_status/')
        params = {'job': job_id, 'format': 'json', 'limit': 1}
        steps = ['Parameter & data file validation complete.', 'COMPLETE']
        prev_response = ''
        while time.time() < timeout:
            response = client.get(status_url, params=params)
            self.assertEqual(response.status_code, 200,
                             'Expected to get valid response back')
            if len(response.text):
                json_data = response.json()
                if prev_response <> response.text:
                    logger.debug('Reponse changed to %s', response.text)
                prev_response = response.text
                if json_data['meta']['total_count']:
                    if json_data['objects'][0]['message'] in steps:
                        steps.remove(json_data['objects'][0]['message'])
                    if json_data['objects'][0]['message'] == 'COMPLETE':
                        break
            time.sleep(.1)
        self.assertEqual(len(steps), 0,
                         'Did not get expected message(s) %s' % (steps, ))

        response = client.get(job_uri, params={'format': 'json'})
        json_response = response.json()
        self.assertTrue(
            json_response['status'] in ('Post-processing results', 'Complete'),
            'Expected a status of Complete, not %s' %
            (json_response['status']))

        timeout = time.time() + 120
        while time.time() < timeout:
            if json_response['status'] == 'Complete':
                break
            response = client.get(job_uri, params={'format': 'json'})
            json_response = response.json()
            time.sleep(.1)
        else:
            self.fail(
                'Expected status to be complete after 120s timeout, not %s' %
                (json_response['status']))
        results_uri = None
        for row in json_response['results_files']:
            if row['primary']:
                logger.debug("Primary results were %s", row)
                results_uri = client.getURL(path=row['datafile'])
        if not results_uri:
            self.fail(
                'Expected to get back a primary result, none found in %s' %
                (json_response, ))
        # Try to see if another user can download this job or results..
        username2, password2 = self.getUsernamePassword()
        user_uri = self._create_user(username2, password2)
        client2 = NMTKClient(self.site_url)
        client2.login(username=username2, password=password2)
        response = client2.get(job_uri, params={'format': 'json'})
        self.assertEqual(response.status_code, 401,
                         ('Expected 401 forbidden when ' +
                          'another user tried to get job info (not %s)') %
                         (response.status_code, ))
        response = client2.get(results_uri, params={'format': 'json'})
        self.assertEqual(response.status_code, 401,
                         ('Expected 401 forbidden when ' +
                          'another user tried to get result (not %s)') %
                         (response.status_code, ))

        response = client.get(results_uri, params={'format': 'json'})
        self.assertEqual(
            response.status_code, 200,
            'Status code expected was 200, not %s' % (response.status_code, ))
        logger.debug('Header is %s', response.headers)

        data = json.loads(response.content)
コード例 #26
0
 def test_create_delete_user(self):
     '''
     Verify that we can create a user via the API, and delete a user via the API
     In this case we will also validate that users, once deleted, are 
     effectively neutered via the UI.  The same is true for a logged in user
     whose account is deleted while the user is logged in.
     '''
     payload={'format': 'json',
              'limit': 999,
              'all': True }
     response=self.client.get(self.api_user_url, params=payload)
     user_count=response.json()['meta']['total_count']
     # Create the user
     username, password=self.getUsernamePassword()
     response=self._create_user(username, password)
     self.assertEqual(201, response.status_code,
                      'Expected status code of 201, not %s' % 
                      (response.status_code))
     user_uri=response.headers['location']
     response=self.client.get(user_uri, params=payload)
     self.assertEqual(response.status_code, 200, 'Expected to get user data, not %s (%s)'%
                      (response.status_code, response.text))
     logger.debug('Response was %s', response.json())
     # Get a list of users, verifying that user is there
     response=self.client.get(self.api_user_url, params=payload)
     
     json_data=response.json()
     # Verify we have one more user than before
     self.assertEqual(user_count+1, json_data['meta']['total_count'],
                      'Final count of users is %s, expected %s' % 
                      (json_data['meta']['total_count'],
                       user_count+1))
     # Verify that the user we created exists
     usernames=[rec['username'] for rec in json_data['objects']]
     self.assertTrue(username in usernames, 
                     'Username %s not found in %s' % 
                     (username, ','.join(usernames)))
     
     # Verify we can get the user via a query
     payload2=payload.copy()
     payload2['username']= username
     response=self.client.get(self.api_user_url, params=payload2)
     json_data=response.json()
     logger.debug('Response was %s', response.text)
     self.assertEqual(1, json_data['meta']['total_count'],
                      'Retrieve record for ONLY %s, got %s records back' % 
                      (username,
                       json_data['meta']['total_count']))
     
     # Verify that the user we created exists (just copy the check from above,
     # because I am lazy - and this works the same)
     usernames=[rec['username'] for rec in json_data['objects']]
     self.assertTrue(username in usernames, 
                     'Username %s not found in %s' % 
                     (username, ','.join(usernames)))
     
     # MAke sure that meta wasn't lying, and we really only got one record back.
     self.assertEqual(len(usernames),1,msg='More than one user returned from query')
     
     # Verify we can login as the newly created user.
     client=NMTKClient(self.site_url)
     response=client.login(username, password)
     logger.debug('Response from login was %s', response.status_code)
     self.assertEqual(response.status_code,302,
                      'Login did not produce expected redirect')
     self.assertTrue(len(response.headers.get('location')),
                     'Redirect location header expected, not provided')
     response=client.get(client.getURL(path=''),
                         allow_redirects=False)
     self.assertEqual(200, response.status_code,
                      'Unexpected redirect retrieving protected URI')
             
     # Delete the user we just created
     response=self._delete_user(user_uri)
     self.assertEqual(204, response.status_code)
     
     # Try to access a protected URL
     response=client.get(client.getURL(path=self.protected_url),
                         allow_redirects=False)
     self.assertEqual(302, response.status_code,
                      'Deleted user should not be able to access a' +
                      ' protected URI')
     
     # Try to login again as the disabled user:
     client=NMTKClient(self.site_url)
     response=client.login(username, password)
     self.assertEqual(200, response.status_code,
                      'Login for deleted user should fail')
     
     response=client.get(client.getURL(path=self.protected_url),
                         allow_redirects=False)
     self.assertEqual(302, response.status_code,
                      'Deleted user should not be able to access a' +
                      ' protected URI')
コード例 #27
0
 def getClient(self):
     return NMTKClient(self.site_url,
                       verify_ssl=self.verify_ssl)
コード例 #28
0
    def test_prevent_user_from_using_other_user_data(self):
        '''
        Verify that one user can neither access, nor submit jobs, with another users data
        '''
        username, password=self.getUsernamePassword()
        user_uri=self._create_user(username,password)
        username2, password2=self.getUsernamePassword()
        user_uri=self._create_user(username2,password2)
        client=NMTKClient(self.site_url)
        client.login(username=username,
                     password=password)
        client2=NMTKClient(self.site_url)
        client2.login(username=username2,
                      password=password2)
        filename=self.get_support_file('test1.geojson')
        test_file=client.uploadData(filename, 
                                    description='Test configuration file')
        # Just try to access the other users file
        response=client2.get(test_file, params={'format': 'json'})
        logger.debug('Response when getting other users file was %s',
                     response.status_code)
        self.assertEqual(response.status_code, 401,
                         'Expected a 401, got a %s' % (response.status_code,))
        # Try to create a job with the other users file
        job_url=client.getURL('api','job/')
        tool_url=client.getURL('api','tool/')

        response=client.get(tool_url, params={'format': 'json'})
        tools=response.json()['objects']
        # Get a list of all the Tool Resource URIs for Minnesota models,
        # since the test1.geojson file is a MN model-specific data file.
        for tool in tools:
            if 'umn' in tool['name'].lower():
                tool_uri=tool['resource_uri']
                break
        data={'tool': client.neuter_url(tool_uri),
              'description': 'how now brown cow'}
        logger.debug('Verifying that user A cannot create a job with User B data')
        response=client2.post(job_url, 
                              data=json.dumps(data),
                              headers={'Content-Type': 'application/json',})
        logger.debug('Status code was %s', response.status_code)
        logger.debug('Response text was %s', response.text)
コード例 #29
0
 def getNMTKClient(self, *args, **kwargs):
     return NMTKClient(self.site_url,
                       verify_ssl=self.verify_ssl)
コード例 #30
0
    def test_user_change_password(self):
        '''
        Verify that password change functionality functions as designed.
        '''
        payload={'format': 'json' }
        response=self.client.get(self.api_user_url, params=payload)
        
        # Create the user
        username, password=self.getUsernamePassword()
        response=self._create_user(username, password)
        user_url=response.headers['location']
        # Create the user
        username2, password2=self.getUsernamePassword()
        response=self._create_user(username2, password2)
        user2_url=response.headers['location']
        
        client=NMTKClient(self.site_url)
        response=client.login(username, password)
        
        client2=NMTKClient(self.site_url)
        response=client2.login(username2, password2)
        
        client_data=client.get(user_url).json()
        client2_data=client2.get(user2_url).json()
        
        # user changes his own password, but fails to supply old password
        client_data['password']='******' % (password,)
        response=client.put(user_url, data=json.dumps(client_data))
        self.assertEqual(response.status_code, 400,
                         'Without old password password change should fail')
        
        # login with new password
        client_a=NMTKClient(self.site_url)
        response=client_a.login(username, client_data['password'])
        self.assertEqual(response.status_code, 200,
                         'Redirect not expected after unsuccessful login (pw not changed)') 
          
        # user changes his own password, but supplys bad old password
        client_data['current_password']='******' % (password,)
        response=client.put(user_url, data=json.dumps(client_data))
        self.assertEqual(response.status_code, 400,
                         'Without old password password change should fail')
        
        # login with new password
        client_a=NMTKClient(self.site_url)
        response=client_a.login(username, client_data['password'])
        self.assertEqual(response.status_code, 200,
                         'Redirect not expected after unsuccessful login (pw not changed)')   
                
        # user changes his own password, but fails to supply old password
        client_data['current_password']=password
        client.put(user_url, data=json.dumps(client_data))    
        
        # login with new password
        client_a=NMTKClient(self.site_url)
        response=client_a.login(username, client_data['password'])
        self.assertEqual(response.status_code, 302,
                         'Redirect expected after successful login')        

        
        # Verify old password no longer works
        response=client_a.login(username, password)
        self.assertEqual(response.status_code, 200,
                         'Redirect not expected after login ' + 
                         'attempt with old password')
        
        # User tries to change another users password
        client2_data['password']=password
        response=client.put(user2_url, data=json.dumps(client2_data),
                            headers={'Content-Type': 'application/json',})
        self.assertEqual(401, response.status_code,
                         'Expected to get a 401 (Unauthorized) when a ' +
                         'non-superuser tries to change another users password')
        
        # Verify old password still works
        response=client_a.login(username2, password2)
        self.assertEqual(response.status_code, 302,
                         'Redirect expected after login ' + 
                         'attempt with original password')
        
        # Superuser tries to change user password.
        logger.debug(self.client.get(self.api_user_url, params={'format': 'json'}).json())
        logger.debug('Client data is %s', client2_data)
        response=self.client.put(user2_url, 
                                 data=json.dumps(client2_data),
                                 headers={'Content-Type': 'application/json',})
        logger.debug('Response from put was %s: %s', response.status_code, response.text)
        self.assertTrue(response.status_code in (202,204),
                         'Expected to get a 204 when a ' +
                         'superuser tries to change another users password')
        
        # Verify password change worked
        client2_a=NMTKClient(self.site_url)
        response=client2_a.login(username2, password)
        self.assertEqual(response.status_code, 302,
                         'Redirect expected after successful login')
        
        # Verify old password no longer works
        response=client2_a.login(username2, password2)
        self.assertEqual(response.status_code, 200,
                         'Redirect not expected after login ' + 
                         'attempt with old password')
コード例 #31
0
ファイル: NMTKTestCase.py プロジェクト: jrawbits/nmtk-1
class NMTKTestCase(unittest.TestCase):

    def _id_generator(self, size=6,
                      chars=(string.ascii_lowercase +
                             string.ascii_uppercase +
                             string.digits)):
        return ''.join(random.choice(chars) for x in range(size))

    def getUsernamePassword(self):
        return (self._id_generator(), self._id_generator())

    def _getSiteConfigDynamic(self):
        try:
            command = ['python',
                       self.settings_command,
                       'create_config']
            proc = subprocess.Popen(command, stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            out, err = proc.communicate()
            config = json.loads(err)
            self.delusers.append(config['username'])
            # Stderr contains the config output.
            return config
        except Exception as e:
            logger.exception('Failed to get dynamic config!')

        return None

    def _getSiteConfigStatic(self):
        config_file = os.path.join(nmtk_path, 'tests/config.json')
        if os.path.exists(config_file):
            try:
                config = json.loads(open(config_file).read())
                return config
            except:
                pass
        return None

    def _getSiteConfig(self):
        config = self._getSiteConfigDynamic() or self._getSiteConfigStatic()
        if config:
            return config
        raise Exception('No valid config found (tried both dynamic and static')

    def setUp(self):
        self.settings_command = os.path.join(nmtk_path,
                                             'NMTK_apps/manage.py')
        self.delusers = []
        config = self._getSiteConfig()

        self.support_files = os.path.join(nmtk_path, 'tests/support_files')
        self.site_url = config['site_url']
        self.username = config['username']
        self.password = config['password']
        self.client = NMTKClient(self.site_url)
        self.client.login(self.username, self.password)
        self.api_user_url = self.client.getURL('api', 'user/')
        self.api_file_url = self.client.getURL('api', 'datafile/')

    def get_support_file(self, fn):
        return os.path.join(self.support_files, fn)

    def tearDown(self):
        '''
        Use the management purge_users command to purge the users created
        during testing from the database.
        '''
        if self.delusers:
            command = ['python',
                       self.settings_command,
                       'purge_users'] + self.delusers
            with open(os.devnull, "w") as fnull:
                subprocess.call(command, stdout=fnull, stderr=fnull)

    def _create_user(self, *args, **kwargs):
        '''
        A helper method to create a new user, given a password and userid
        '''
        if len(args) == 2:
            kwargs['username'] = args[0]
            kwargs['password'] = args[1]
        for key in ('username', 'password'):
            kwargs.setdefault(key, self._id_generator())

        response = self.client.create_user(**kwargs)
        self.delusers.append(kwargs['username'])
        return response

    def _delete_user(self, url):
        response = self.client.delete(url)
        logger.debug('Deleted %s with status code of %s',
                     url, response.status_code)
        return response
コード例 #32
0
 def test_submit_job_other_user_denied_access(self):
     '''
     Verify that once a job is submitted/created, other users cannot access.
     '''
     username, password=self.getUsernamePassword()
     user_uri=self._create_user(username,password)
     client=NMTKClient(self.site_url)
     response=client.login(username=username,
                           password=password)
     username2, password2=self.getUsernamePassword()
     user_uri2=self._create_user(username2,password2)
     client2=NMTKClient(self.site_url)
     client2.login(username=username2,
                   password=password2)
     filename=self.get_support_file('test1.geojson')
     test_file=client.uploadData(filename, 
                                 description='Test data file (MSP)')
     logger.debug('URI of test file is %s', test_file)
     
     tool_url=client.getURL('api','tool/')
     job_url=client.getURL('api','job/')
     response=client.get(tool_url, params={'format': 'json'})
     tools=response.json()['objects']
     # Get a list of all the Tool Resource URIs for Minnesota models,
     # since the test1.geojson file is a MN model-specific data file.
     for tool in tools:
         if 'umn' in tool['name'].lower():
             tool_uri=tool['resource_uri']
             break
     data={'tool': client.neuter_url(tool_uri),
           'description': 'how now brown cow'}
     
     response=client.post(job_url, 
                          data=json.dumps(data),
                          headers={'Content-Type': 'application/json',})
     self.assertEqual(response.status_code, 201,
                      ('Expected job to be created - ' +
                       'got back %s instead') % (response.status_code,))
     job_uri=response.headers['location']
     # Now we have a job, let's get the form, generate the response, and
     # submit it back to the user.
     response=client2.get(job_uri, params={'format': 'json'})
     self.assertEqual(response.status_code, 401,
                      'Expected client2 to get a 401, not %s' % 
                      (response.status_code,))