def test_change_users_settings_file(self): with models.session(self.app) as session: users = session.query(models.User).all() # assert user with total for u in users: if u.email == "*****@*****.**": assert u.path_restriction_reg == ".*" assert len(users) == 4 with open(os.path.join(self.source, 'users.txt'), 'w') as opn: opn.write("""[ {"email": "*****@*****.**"}, {"email": "*****@*****.**", "path_restriction_reg": "/ZE_2012"} ]""") initdbusers(self.app) with models.session(self.app) as session: users2 = session.query(models.User).all() assert len(users2) == 2 # check that we updated user1: with models.session(self.app) as session: users = session.query(models.User).all() for u in users: if u.email == "*****@*****.**": assert u.path_restriction_reg is None
def initdbusers(app): """Initializes the users according to the json uers file Users will be updated/ added /removed according to the file """ dbpath = _dbpath(app) if not dbpath: return file_ = os.path.join(dbpath, "users.txt") if not os.path.isfile(file_): return with session(app) as sess: jsonfile_emails = [] jsonlines = [] with open(file_, "r") as opn: for line in opn: if not line.strip().startswith('#'): jsonlines.append(line) users = json.loads("\n".join(jsonlines)) docommit = False for jsonuser in users: user = User(**jsonuser) email = user.email if not email or '@' not in email[1:-1]: continue jsonfile_emails.append(email) dbuser = sess.query(User).filter(User.email == email).first() if dbuser and user.path_restriction_reg != dbuser.path_restriction_reg: dbuser.path_restriction_reg = user.path_restriction_reg sess.commit() # need to commit now otherwise dbuser instance might be replaced? elif not dbuser: # new user docommit = True sess.add(user) if docommit: sess.commit() # commit once now docommit = False # now delete unused users: if jsonfile_emails: jsonfile_emails = set(jsonfile_emails) for dbuser in sess.query(User): if dbuser.email not in jsonfile_emails: docommit = True sess.delete(dbuser) if docommit: sess.commit() # commit once now
def test_report_views_auth(self, mock_reportbuild_run): # test the page pdf. We are unauthorized, so this should give us error: with self.app.test_request_context(): app = self.app.test_client() # If we add routes with the slash at the end, we should # add follow_redirect=True to app.get. See # http://flask.pocoo.org/docs/0.11/quickstart/#routing res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should ahve an html page: assert res.status_code == 401 assert mock_reportbuild_run.call_count == 0 # now try to login: # with a non-registered email res = app.post("/ZE_2012/login", data={'email': 'abc'}) assert res.status_code == 401 # thus, we do not access the pdf creation: res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should ahve an html page: assert res.status_code == 401 assert mock_reportbuild_run.call_count == 0 # now try to login: # with a registered email and wrong permission res = app.post("/ZE_2012/login", data={'email': '*****@*****.**'}) assert res.status_code == 403 # thus, we do not access the pdf creation: res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should ahve an html page: assert res.status_code == 401 assert mock_reportbuild_run.call_count == 0 # now try to login: # with another non registered email res = app.post("/ZE_2012/login", data={'email': '*****@*****.**'}) assert res.status_code == 200 # check that the current user has the fields written with models.session(self.app) as session: user = session.query(models.User).filter( models.User.email == '*****@*****.**').first() assert user.editing_path is not None assert user.login_date is not None # now try to login with another user: res = app.post("/ZE_2012/login", data={'email': '*****@*****.**'}) assert res.status_code == 409 # now logout res = app.post("/ZE_2012/logout") # check that the current user has the fields written with models.session(self.app) as session: user = session.query(models.User).filter( models.User.email == '*****@*****.**').first() assert user.editing_path is None assert user.login_date is None # and re-login with user1: res = app.post("/ZE_2012/login", data={'email': '*****@*****.**'}) assert res.status_code == 200 # trying to re-login with the same user has no effect: res = app.post("/ZE_2012/login", data={'email': '*****@*****.**'}) assert res.status_code == 200 # but w need to setup urlread for the arcgis image, because we mocked it # (FIXME: we mocked in gfzreport.templates.network.core.utils.urllib2.urlopen, # why is it mocked in map module?!!!) # The signature is: # _get_urlopen_sideeffect(geofon_retval=None, others_retval=None): # Thus, we setup others_retval=URLError, which means that if 'geofon' is not in url # (which is the case for arcgis query) and URLException is raised. # This way, the map is generated with drawcostallines # and the pdf is created. Keep in mind that pdflatex will raise in any case self.mock_urlopen.side_effect = _get_urlopen_sideeffect( None, URLError('wat')) res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should have an html page: assert res.status_code == 200 assert mock_reportbuild_run.call_count == 1 # check commits: res = app.post("/ZE_2012/get_commits", content_type='application/json') assert res.status_code == 200 commitz = json.loads(res.data) assert len(commitz) == 1 commit = commitz[0] assert commit['email'] == '*****@*****.**' assert "pdf: Build successful, no compilation error" in commit[ 'notes'] # Now modify the source rst by putting a non-found image: mock_reportbuild_run.reset_mock() self.modifyrst("", ".. figure:: whatever_data_not_found_blabla.png") res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should have an html page: assert res.status_code == 200 assert mock_reportbuild_run.call_count == 1 # check commits: res = app.post("/ZE_2012/get_commits", content_type='application/json') assert res.status_code == 200 commitz = json.loads(res.data) assert len(commitz) == 2 commit = commitz[0] # this is the last commit assert commit['email'] == '*****@*****.**' assert "pdf: Build successful, with compilation errors" in commit[ 'notes'] # check logs: res = app.post("/ZE_2012/get_logs", data=json.dumps({'buildtype': 'pdf'}), content_type='application/json') assert res.status_code == 200 _data = json.loads(res.data) # _data has two elements: the standard error (plus some titles added, such as # 'Sphinx build') and the standard error showing only relevant errors/warnings: these # are lines recognizable by a special format (using regexps) and that are more # informative for the web user than the all standard error, which might be too verbose. # (The the standard error showing only relevant errors/warnings can be shown by means # of a checkobx on the GUI) assert len(_data) == 2 # first string is the whole log file, must be greater than the second one (errors only): assert len(_data[0]) > len(_data[1]) errlogcontent = _data[1] # sphinx build (rst to latex) was successfull: assert 'No compilation error found' in errlogcontent[:errlogcontent .find( 'Pdflatex' )] # pdflatex gave some error(s): if we fix this in the future, it might have no errors, # in case check errlogcontent and assert something else or comment out the following assertion: assert "ERROR:" in errlogcontent[errlogcontent.find('Pdflatex'):] mock_reportbuild_run.reset_mock() # test that we do not call mock_reportbuild_run # once again: res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should ahve an html page: assert res.status_code == 200 # assert we did not call mock_reportbuild again: assert mock_reportbuild_run.call_count == 0
def test_report_views_auth(self, mock_reportbuild_run): # test the page pdf. We are unauthorized, so this should give us error: with self.app.test_request_context(): app = self.app.test_client() # If we add routes with the slash at the end, we should # add follow_redirect=True to app.get. See # http://flask.pocoo.org/docs/0.11/quickstart/#routing res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should ahve an html page: assert res.status_code == 401 assert mock_reportbuild_run.call_count == 0 # now try to login: # with a non-registered email res = app.post("/ZE_2012/login", data={'email' :'abc'}) assert res.status_code == 401 # thus, we do not access the pdf creation: res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should ahve an html page: assert res.status_code == 401 assert mock_reportbuild_run.call_count == 0 # now try to login: # with a registered email and wrong permission res = app.post("/ZE_2012/login", data={'email' :'*****@*****.**'}) assert res.status_code == 403 # thus, we do not access the pdf creation: res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should ahve an html page: assert res.status_code == 401 assert mock_reportbuild_run.call_count == 0 # now try to login: # with another non registered email res = app.post("/ZE_2012/login", data={'email' :'*****@*****.**'}) assert res.status_code == 200 # check that the current user has the fields written with models.session(self.app) as session: user = session.query(models.User).filter(models.User.email == '*****@*****.**').first() assert user.editing_path is not None assert user.login_date is not None # now try to login with another user: res = app.post("/ZE_2012/login", data={'email' :'*****@*****.**'}) assert res.status_code == 409 # now logout res = app.post("/ZE_2012/logout") # check that the current user has the fields written with models.session(self.app) as session: user = session.query(models.User).filter(models.User.email == '*****@*****.**').first() assert user.editing_path is None assert user.login_date is None # and re-login with user1: res = app.post("/ZE_2012/login", data={'email' :'*****@*****.**'}) assert res.status_code == 200 # trying to re-login with the same user has no effect: res = app.post("/ZE_2012/login", data={'email' :'*****@*****.**'}) assert res.status_code == 200 # but w need to setup urlread for the arcgis image, because we mocked it # (FIXME: we mocked in gfzreport.templates.network.core.utils.urllib2.urlopen, # why is it mocked in map module?!!!) # The signature is: # _get_urlopen_sideeffect(geofon_retval=None, others_retval=None): # Thus, we setup others_retval=URLError, which means that if 'geofon' is not in url # (which is the case for arcgis query) and URLException is raised. # This way, the map is generated with drawcostallines # and the pdf is created. Keep in mind that pdflatex will raise in any case self.mock_urlopen.side_effect = _get_urlopen_sideeffect(None, URLError('wat')) res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should have an html page: assert res.status_code == 200 assert mock_reportbuild_run.call_count == 1 # check commits: res = app.post("/ZE_2012/get_commits", content_type='application/json') assert res.status_code == 200 commitz = json.loads(res.data) assert len(commitz) == 1 commit = commitz[0] assert commit['email'] == '*****@*****.**' assert "pdf: Build successful, no compilation error" in commit['notes'] # Now modify the source rst by putting a non-found image: mock_reportbuild_run.reset_mock() self.modifyrst("", ".. figure:: whatever_data_not_found_blabla.png") res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should have an html page: assert res.status_code == 200 assert mock_reportbuild_run.call_count == 1 # check commits: res = app.post("/ZE_2012/get_commits", content_type='application/json') assert res.status_code == 200 commitz = json.loads(res.data) assert len(commitz) == 2 commit = commitz[0] # this is the last commit assert commit['email'] == '*****@*****.**' assert "pdf: Build successful, with compilation errors" in commit['notes'] # check logs: res = app.post("/ZE_2012/get_logs", data=json.dumps({'buildtype': 'pdf'}), content_type='application/json') assert res.status_code == 200 _data = json.loads(res.data) # _data has two elements: the standard error (plus some titles added, such as # 'Sphinx build') and the standard error showing only relevant errors/warnings: these # are lines recognizable by a special format (using regexps) and that are more # informative for the web user than the all standard error, which might be too verbose. # (The the standard error showing only relevant errors/warnings can be shown by means # of a checkobx on the GUI) assert len(_data) == 2 # first string is the whole log file, must be greater than the second one (errors only): assert len(_data[0]) > len(_data[1]) errlogcontent = _data[1] # sphinx build (rst to latex) was successfull: assert 'No compilation error found' in errlogcontent[:errlogcontent.find('Pdflatex')] # pdflatex gave some error(s): if we fix this in the future, it might have no errors, # in case check errlogcontent and assert something else or comment out the following assertion: assert "ERROR:" in errlogcontent[errlogcontent.find('Pdflatex'):] mock_reportbuild_run.reset_mock() # test that we do not call mock_reportbuild_run # once again: res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should ahve an html page: assert res.status_code == 200 # assert we did not call mock_reportbuild again: assert mock_reportbuild_run.call_count == 0
def test_report_remember_cookie_duration(self, mock_reportbuild_run): duration = self.app.config['PERMANENT_SESSION_LIFETIME'] # test the page pdf. We are unauthorized, so this should give us error: with self.app.test_request_context(): app = self.app.test_client() # If we add routes with the slash at the end, we should # add follow_redirect=True to app.get. See # http://flask.pocoo.org/docs/0.11/quickstart/#routing res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should ahve an html page: assert res.status_code == 401 assert mock_reportbuild_run.call_count == 0 # now try to login: # with a non-registered email res = app.post("/ZE_2012/login", data={'email' :'abc'}) assert res.status_code == 401 # thus, we do not access the pdf creation: res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should ahve an html page: assert res.status_code == 401 assert mock_reportbuild_run.call_count == 0 # now try to login: # with a registered email and wrong permission res = app.post("/ZE_2012/login", data={'email' :'*****@*****.**'}) assert res.status_code == 403 # thus, we do not access the pdf creation: res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should ahve an html page: assert res.status_code == 401 assert mock_reportbuild_run.call_count == 0 # now try to login: # with another non registered email res = app.post("/ZE_2012/login", data={'email' :'*****@*****.**'}) assert res.status_code == 200 # check that the current user has the fields written with models.session(self.app) as session: user = session.query(models.User).filter(models.User.email == '*****@*****.**').first() assert user.editing_path is not None assert user.login_date is not None # sleep two seconds and see that we should have been logged out from the session # (we set REMEMBER_COOKIE_DURATION = 1 second) time.sleep(duration.total_seconds()+1) # Note that we need to setup urlread for the arcgis image, because we mocked it # (FIXME: we mocked in gfzreport.templates.network.core.utils.urllib2.urlopen, # why is it mocked in map module?!!!) # The signature is: # _get_urlopen_sideeffect(geofon_retval=None, others_retval=None): # Thus, we setup others_retval=URLError, which means that if 'geofon' is not in url # (which is the case for arcgis query) and URLException is raised. # This way, the map is generated with drawcostallines # and the pdf is created. Keep in mind that pdflatex will raise in any case self.mock_urlopen.side_effect = _get_urlopen_sideeffect(None, URLError('wat')) res = app.get("/ZE_2012/pdf", follow_redirects=True) # few stupid asserts, the main test is not raising # we should have an html page. But login session should have been expired! assert res.status_code == 401 assert mock_reportbuild_run.call_count == 0 # now try to login again: # with another non registered email usrname = 'user2_ok' res = app.post("/ZE_2012/login", data={'email' :'*****@*****.**' % usrname}) assert res.status_code == 200 # now try to login with another user. This should fail as we are still in # the session duration: # with another non registered email res = app.post("/ZE_2012/login", data={'email' :'*****@*****.**'}) assert res.status_code == 409 # conflict assert ("Conflict: user '%s' is editing the same report (or forgot to log out): " "by default, his/her session will expire in 0:00:" % usrname) in json.loads(res.data)['message'] # sleep two seconds and see that we should have been logged out from the session # (we set REMEMBER_COOKIE_DURATION = 1 second) time.sleep(duration.total_seconds()+1) # now try to login with the same user. As first user's session time expired, # we should be able to login: res = app.post("/ZE_2012/login", data={'email' :'*****@*****.**'}) assert res.status_code == 200
def load_user(user_id): with session(app) as sess: return sess.query(User).filter(User.id == int(user_id)).first()