예제 #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_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,))
예제 #3
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)
예제 #4
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')
예제 #5
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')
예제 #6
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)