Ignore:
Timestamp:
30 Nov 2018, 07:34:44 (6 years ago)
Author:
Henrik Bettermann
Message:

Do not allow uploading data with trailing whitespaces.

Location:
main/waeup.ikoba/trunk
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.ikoba/trunk/CHANGES.txt

    r15257 r15258  
    440.2.dev0 (unreleased)
    55=====================
     6
     7* Do not allow uploading data with trailing whitespaces.
     8
     9* Set ssl index URL in buildout.cfg
    610
    711* Remove 'hidden' attribute from ordereddSelectionList which has
  • main/waeup.ikoba/trunk/src/waeup/ikoba/browser/pages.py

    r14221 r15258  
    11421142            invalid_line = check_csv_charset(filecontent.splitlines())
    11431143            if invalid_line:
    1144                 self.flash(_(
    1145                     "Your file contains forbidden characters or "
    1146                     "has invalid CSV format. "
    1147                     "First problematic line detected: line %s. "
    1148                     "Please replace." % invalid_line), type='danger')
     1144                if invalid_line == -1:
     1145                    self.flash(_(
     1146                        "The data in your file contain trailing whitespaces."
     1147                        "Please replace."), type='danger')
     1148                else:
     1149                    self.flash(_(
     1150                        "Your file contains forbidden characters or "
     1151                        "has invalid CSV format. "
     1152                        "First problematic line detected: line %s. "
     1153                        "Please replace." % invalid_line), type='danger')
    11491154                logger.info('%s - invalid file uploaded: %s' %
    11501155                            (ob_class, target))
  • main/waeup.ikoba/trunk/src/waeup/ikoba/browser/tests/test_browser.py

    r14173 r15258  
    3636from waeup.ikoba.tests.test_async import FunctionalAsyncTestCase
    3737
     38SAMPLE_FILE = os.path.join(os.path.dirname(__file__), 'test_file.csv')
     39FORBIDDEN_FILE = os.path.join(os.path.dirname(__file__), 'forbidden_file.csv')
     40FORBIDDEN_FILE_2 = os.path.join(
     41    os.path.dirname(__file__), 'forbidden_file_2.csv')
    3842
    3943class CompanySetup(FunctionalTestCase):
     
    133137            self.datacenter_path + "/@@show/?logname=myspecial.log&query=.*")
    134138        assert "SOME <TAG> AND ÜMLÄUTS IN LOG" in self.browser.contents
     139
     140    def test_file_download_delete(self):
     141        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
     142        self.browser.open(self.datacenter_path)
     143        self.assertEqual(self.browser.headers['Status'], '200 Ok')
     144        self.assertEqual(self.browser.url, self.datacenter_path)
     145        self.browser.getLink("Upload data").click()
     146        file = open(SAMPLE_FILE)
     147        ctrl = self.browser.getControl(name='uploadfile:file')
     148        file_ctrl = ctrl.mech_control
     149        file_ctrl.add_file(file, filename='my_test_data.csv')
     150        self.browser.getControl('Upload').click()
     151        self.browser.open(self.datacenter_path)
     152        self.browser.getLink('my_test_data_zope.mgr.csv').click()
     153        self.assertEqual(self.browser.headers['Status'], '200 Ok')
     154        self.assertEqual(self.browser.headers['Content-Type'],
     155                         'text/csv; charset=UTF-8')
     156        logfile = os.path.join(
     157            self.app['datacenter'].storage, 'logs', 'datacenter.log')
     158        logcontent = open(logfile).read()
     159        self.assertTrue('zope.mgr - browser.pages.FileDownloadView - '
     160                        'downloaded: my_test_data_zope.mgr.csv' in logcontent)
     161        self.browser.open(self.datacenter_path)
     162        ctrl = self.browser.getControl(name='val_id')
     163        ctrl.getControl(value='my_test_data_zope.mgr.csv').selected = True
     164        self.browser.getControl("Remove selected", index=0).click()
     165        self.assertTrue('Successfully deleted: my_test_data_zope.mgr.csv'
     166            in self.browser.contents)
     167        logcontent = open(logfile).read()
     168        self.assertTrue('zope.mgr - browser.pages.DatacenterPage - '
     169                        'deleted: my_test_data_zope.mgr.csv' in logcontent)
     170        return
     171
     172    def test_forbidden_file_upload(self):
     173        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
     174        self.browser.open(self.datacenter_path)
     175        self.assertEqual(self.browser.headers['Status'], '200 Ok')
     176        self.assertEqual(self.browser.url, self.datacenter_path)
     177        self.browser.getLink("Upload data").click()
     178        file = open(FORBIDDEN_FILE)
     179        ctrl = self.browser.getControl(name='uploadfile:file')
     180        file_ctrl = ctrl.mech_control
     181        file_ctrl.add_file(file, filename='my_corrupted_file.csv')
     182        self.browser.getControl('Upload').click()
     183        self.assertTrue(
     184            'Your file contains forbidden characters or'
     185            in self.browser.contents)
     186        logfile = os.path.join(
     187            self.app['datacenter'].storage, 'logs', 'datacenter.log')
     188        logcontent = open(logfile).read()
     189        self.assertTrue('zope.mgr - browser.pages.DatacenterUploadPage - '
     190            'invalid file uploaded:' in logcontent)
     191        return
     192
     193    def test_forbidden_file_upload_2(self):
     194        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
     195        self.browser.open(self.datacenter_path)
     196        self.assertEqual(self.browser.headers['Status'], '200 Ok')
     197        self.assertEqual(self.browser.url, self.datacenter_path)
     198        self.browser.getLink("Upload data").click()
     199        file = open(FORBIDDEN_FILE_2)
     200        ctrl = self.browser.getControl(name='uploadfile:file')
     201        file_ctrl = ctrl.mech_control
     202        file_ctrl.add_file(file, filename='my_corrupted_file.csv')
     203        self.browser.getControl('Upload').click()
     204        self.assertTrue(
     205            'The data in your file contain trailing whitespaces.'
     206            in self.browser.contents)
     207        logfile = os.path.join(
     208            self.app['datacenter'].storage, 'logs', 'datacenter.log')
     209        logcontent = open(logfile).read()
     210        self.assertTrue('zope.mgr - browser.pages.DatacenterUploadPage - '
     211            'invalid file uploaded:' in logcontent)
     212        return
    135213
    136214    def test_user_data_import_permission(self):
  • main/waeup.ikoba/trunk/src/waeup/ikoba/utils/helpers.py

    r13135 r15258  
    756756
    757757def check_csv_charset(iterable):
    758     """Check contents of `iterable` regarding valid CSV encoding.
     758    """Check contents of `iterable` regarding valid CSV encoding and
     759    trailing whitespaces in data.
    759760
    760761    `iterable` is expected to be an iterable on _rows_ (not
     
    764765
    765766    Returns line num of first illegal char or ``None``. Line nums
    766     start counting with 1 (not zero).
     767    start counting with 1 (not zero). Returns -1 if data contain
     768    trailing whitespaces.
    767769    """
    768770    linenum = 1
    769     reader = csv.DictReader(iterable)
    770771    try:
     772        reader = csv.DictReader(iterable)
    771773        for row in reader:
    772774            linenum += 1
     775            for value in row.values():
     776                if value.endswith(' '):
     777                    return -1
    773778    except UnicodeDecodeError:
    774779        return linenum
  • main/waeup.ikoba/trunk/src/waeup/ikoba/utils/tests/test_helpers.py

    r12434 r15258  
    533533            'some text that \n'
    534534            '\n'      # this empty line will break
    535             'is not a csv file \n' + chr(0x92) + '\n'
     535            'is not a csv file\n' + chr(0x92) + '\n'
    536536            ).splitlines()
    537537        self.assertEqual(helpers.check_csv_charset(csv), 2)
     538
     539    def test_invalid_data3(self):
     540        csv = (
     541            "code,title,title_prefix\n"
     542            "FAC1,Faculty 1,faculty\n"
     543            "FAC2,Faculty 2 ,institute\n"
     544            "FAC3,Fäcülty 3,school\n"
     545            ).splitlines()
     546        self.assertEqual(helpers.check_csv_charset(csv), -1)
    538547
    539548
Note: See TracChangeset for help on using the changeset viewer.