Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
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
Esempio n. 4
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
Esempio n. 5
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
Esempio n. 7
0
 def load_user(user_id):
     with session(app) as sess:
         return sess.query(User).filter(User.id == int(user_id)).first()