diff --git a/requirements.txt b/requirements.txt index fa8422d69..4c29fbe44 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,7 +25,7 @@ Flask-Principal==0.4.0 Flask-SQLAlchemy==2.3.2 Flask-WTF==0.14.3 Flask-Compress==1.4.0 -passlib==1.7.1 +passlib==1.7.2 pytz==2018.9 simplejson==3.16.0 six>=1.12.0 @@ -37,5 +37,5 @@ psutil==5.5.1 psycopg2>=2.8 python-dateutil>=2.8.0 SQLAlchemy>=1.2.18 -Flask-Security>=3.0.0 +Flask-Security-Too>=3.0.0 sshtunnel>=0.1.4 diff --git a/web/pgadmin/browser/__init__.py b/web/pgadmin/browser/__init__.py index 3a54aafe4..30af3e11b 100644 --- a/web/pgadmin/browser/__init__.py +++ b/web/pgadmin/browser/__init__.py @@ -29,7 +29,7 @@ from flask_security.recoverable import reset_password_token_status, \ from flask_security.signals import reset_password_instructions_sent from flask_security.utils import config_value, do_flash, get_url, \ get_message, slash_url_suffix, login_user, send_mail -from flask_security.views import _security, _commit, _render_json, _ctx +from flask_security.views import _security, _commit, default_render_json, _ctx from werkzeug.datastructures import MultiDict import config @@ -952,7 +952,7 @@ if hasattr(config, 'SECURITY_CHANGEABLE') and config.SECURITY_CHANGEABLE: if request.json and not has_error: form.user = current_user - return _render_json(form) + return default_render_json(form) return _security.render_template( config_value('CHANGE_PASSWORD_TEMPLATE'), diff --git a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py index e7e912d36..1d6d7a43e 100644 --- a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py +++ b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py @@ -137,7 +137,7 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest): self.assertIn("from database 'pg_utility_test_db'", str(command)) # On windows a modified path may be shown so skip this test - if os.name is not 'nt': + if os.name != 'nt': self.assertIn("test_backup", str(command)) self.assertIn("pg_dump", str(command)) @@ -203,7 +203,7 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest): text self.assertIn(self.server['name'], str(command)) - if os.name is not 'nt': + if os.name != 'nt': self.assertIn("test_backup", str(command)) self.assertIn("pg_restore", str(command)) diff --git a/web/pgadmin/tools/backup/tests/test_backup_message.py b/web/pgadmin/tools/backup/tests/test_backup_message.py index 211fdf5f4..a5ba2e9e0 100644 --- a/web/pgadmin/tools/backup/tests/test_backup_message.py +++ b/web/pgadmin/tools/backup/tests/test_backup_message.py @@ -46,9 +46,9 @@ class BackupMessageTest(BaseTestGenerator): ], cmd="/test_path/pg_dump" ), - extected_msg="Backing up the server" + expected_msg="Backing up the server" " 'test_backup_server (localhost:5444)'", - expetced_details_cmd='/test_path/pg_dump --file ' + expected_details_cmd='/test_path/pg_dump --file ' '"backup_file" --host "localhost" ' '--port "5444" --username "postgres" ' '--no-password --database "postgres"' @@ -79,9 +79,9 @@ class BackupMessageTest(BaseTestGenerator): ], cmd="/test_path/pg_dump" ), - extected_msg="Backing up the global objects on the server " + expected_msg="Backing up the global objects on the server " "'test_backup_server (localhost:5444)'", - expetced_details_cmd='/test_path/pg_dump --file "backup_file" ' + expected_details_cmd='/test_path/pg_dump --file "backup_file" ' '--host "localhost"' ' --port "5444" --username "postgres" ' '--no-password --database "postgres"' @@ -112,10 +112,10 @@ class BackupMessageTest(BaseTestGenerator): ], cmd="/test_path/pg_dump" ), - extected_msg="Backing up an object on the server " + expected_msg="Backing up an object on the server " "'test_backup_server (localhost:5444)'" " from database 'postgres'", - expetced_details_cmd='/test_path/pg_dump --file "backup_file" ' + expected_details_cmd='/test_path/pg_dump --file "backup_file" ' '--host "localhost" ' '--port "5444" --username "postgres" ' '--no-password --database "postgres"' @@ -139,9 +139,9 @@ class BackupMessageTest(BaseTestGenerator): ) # Check the expected message returned - self.assertEqual(backup_obj.message, self.extected_msg) + self.assertEqual(backup_obj.message, self.expected_msg) # Check the command obj_details = backup_obj.details(self.class_params['cmd'], self.class_params['args']) - self.assertIn(self.expetced_details_cmd, obj_details) + self.assertIn(self.expected_details_cmd, obj_details) diff --git a/web/pgadmin/tools/backup/tests/test_batch_process.py b/web/pgadmin/tools/backup/tests/test_batch_process.py index f4e8c5c17..9d0b1aee6 100644 --- a/web/pgadmin/tools/backup/tests/test_batch_process.py +++ b/web/pgadmin/tools/backup/tests/test_batch_process.py @@ -9,7 +9,8 @@ import sys -from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc +from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc, \ + current_app from pgadmin.tools.backup import BackupMessage, BACKUP from pgadmin.utils.route import BaseTestGenerator from pickle import dumps, loads @@ -108,65 +109,67 @@ class BatchProcessTest(BaseTestGenerator): @patch('pgadmin.tools.backup.BackupMessage.get_server_details') @patch('pgadmin.misc.bgprocess.processes.Popen') - @patch('pgadmin.misc.bgprocess.processes.current_app') @patch('pgadmin.misc.bgprocess.processes.db') @patch('pgadmin.tools.backup.current_user') @patch('pgadmin.misc.bgprocess.processes.current_user') def runTest(self, current_user_mock, current_user, db_mock, - current_app_mock, popen_mock, get_server_details_mock): - current_user.id = 1 - current_user_mock.id = 1 - current_app_mock.PGADMIN_RUNTIME = False - - def db_session_add_mock(j): - cmd_obj = loads(j.desc) - self.assertTrue(isinstance(cmd_obj, IProcessDesc)) - self.assertEqual(cmd_obj.backup_type, self.class_params['type']) - self.assertEqual(cmd_obj.bfile, self.class_params['bfile']) - self.assertEqual(cmd_obj.database, self.class_params['database']) - self.assertEqual(cmd_obj.cmd, - ' --file "backup_file" ' - '--host "{0}" ' - '--port "{1}" ' - '--username "{2}" ' - '--no-password ' - '--database "{3}"'.format( - self.class_params['host'], - self.class_params['port'], - self.class_params['username'], - self.class_params['database'] - )) - - db_mock.session.add.side_effect = db_session_add_mock - db_mock.session.commit = MagicMock(return_value=True) - - get_server_details_mock.return_value = \ - self.class_params['name'],\ - self.class_params['host'],\ - self.class_params['port'] - - backup_obj = BackupMessage( - self.class_params['type'], - self.class_params['sid'], - self.class_params['bfile'], - *self.class_params['args'], - **{'database': self.class_params['database']} - ) - - p = BatchProcess( - desc=backup_obj, - cmd=self.class_params['cmd'], - args=self.class_params['args'] - ) - - # Check that _create_process has been called - self.assertTrue(db_mock.session.add.called) - - # Check start method - self._check_start(popen_mock, p, backup_obj) - - # Check list method - self._check_list(p, backup_obj) + popen_mock, get_server_details_mock): + with self.app.app_context(): + current_user.id = 1 + current_user_mock.id = 1 + current_app.PGADMIN_RUNTIME = False + + def db_session_add_mock(j): + cmd_obj = loads(j.desc) + self.assertTrue(isinstance(cmd_obj, IProcessDesc)) + self.assertEqual(cmd_obj.backup_type, + self.class_params['type']) + self.assertEqual(cmd_obj.bfile, self.class_params['bfile']) + self.assertEqual(cmd_obj.database, + self.class_params['database']) + self.assertEqual(cmd_obj.cmd, + ' --file "backup_file" ' + '--host "{0}" ' + '--port "{1}" ' + '--username "{2}" ' + '--no-password ' + '--database "{3}"'.format( + self.class_params['host'], + self.class_params['port'], + self.class_params['username'], + self.class_params['database'] + )) + + db_mock.session.add.side_effect = db_session_add_mock + db_mock.session.commit = MagicMock(return_value=True) + + get_server_details_mock.return_value = \ + self.class_params['name'], \ + self.class_params['host'], \ + self.class_params['port'] + + backup_obj = BackupMessage( + self.class_params['type'], + self.class_params['sid'], + self.class_params['bfile'], + *self.class_params['args'], + **{'database': self.class_params['database']} + ) + + p = BatchProcess( + desc=backup_obj, + cmd=self.class_params['cmd'], + args=self.class_params['args'] + ) + + # Check that _create_process has been called + self.assertTrue(db_mock.session.add.called) + + # Check start method + self._check_start(popen_mock, p, backup_obj) + + # Check list method + self._check_list(p, backup_obj) @patch('pgadmin.misc.bgprocess.processes.Process') def _check_start(self, popen_mock, p, backup_obj, process_mock): diff --git a/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py index d45ea02f1..61aa2c11e 100644 --- a/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py +++ b/web/pgadmin/tools/maintenance/tests/test_batch_process_maintenance.py @@ -9,7 +9,8 @@ import sys -from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc +from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc, \ + current_app from pgadmin.tools.maintenance import Message from pgadmin.utils.route import BaseTestGenerator from pickle import dumps, loads @@ -52,62 +53,62 @@ class BatchProcessTest(BaseTestGenerator): cmd="VACUUM VERBOSE;\n" ), expected_msg="Maintenance (Vacuum)", - expetced_details_cmd='VACUUM VERBOSE;' + expected_details_cmd='VACUUM VERBOSE;' )) ] @patch('pgadmin.misc.bgprocess.processes.Popen') - @patch('pgadmin.misc.bgprocess.processes.current_app') @patch('pgadmin.misc.bgprocess.processes.db') @patch('pgadmin.tools.maintenance.Server') @patch('pgadmin.misc.bgprocess.processes.current_user') def runTest(self, current_user_mock, server_mock, db_mock, - current_app_mock, popen_mock): - current_user_mock.id = 1 - current_app_mock.PGADMIN_RUNTIME = False - - class TestMockServer(): - def __init__(self, name, host, port): - self.name = name - self.host = host - self.port = port - - def db_session_add_mock(j): - cmd_obj = loads(j.desc) - self.assertTrue(isinstance(cmd_obj, IProcessDesc)) - self.assertEqual(cmd_obj.query, self.class_params['cmd']) - self.assertEqual(cmd_obj.message, self.expected_msg) - self.assertEqual(cmd_obj.data, self.class_params['data']) - - mock_obj = TestMockServer(self.class_params['username'], - self.class_params['host'], - self.class_params['port']) - mock_result = server_mock.query.filter_by.return_value - mock_result.first.return_value = mock_obj - - db_mock.session.add.side_effect = db_session_add_mock - db_mock.session.commit = MagicMock(return_value=True) - - maintenance_obj = Message( - self.class_params['sid'], - self.class_params['data'], - self.class_params['cmd'] - ) - - p = BatchProcess( - desc=maintenance_obj, - cmd=self.class_params['cmd'], - args=self.class_params['args'] - ) - - # Check that _create_process has been called - self.assertTrue(db_mock.session.add.called) - - # Check start method - self._check_start(popen_mock, p, maintenance_obj) - - # Check list method - self._check_list(p, maintenance_obj) + popen_mock): + with self.app.app_context(): + current_user_mock.id = 1 + current_app.PGADMIN_RUNTIME = False + + class TestMockServer(): + def __init__(self, name, host, port): + self.name = name + self.host = host + self.port = port + + def db_session_add_mock(j): + cmd_obj = loads(j.desc) + self.assertTrue(isinstance(cmd_obj, IProcessDesc)) + self.assertEqual(cmd_obj.query, self.class_params['cmd']) + self.assertEqual(cmd_obj.message, self.expected_msg) + self.assertEqual(cmd_obj.data, self.class_params['data']) + + mock_obj = TestMockServer(self.class_params['username'], + self.class_params['host'], + self.class_params['port']) + mock_result = server_mock.query.filter_by.return_value + mock_result.first.return_value = mock_obj + + db_mock.session.add.side_effect = db_session_add_mock + db_mock.session.commit = MagicMock(return_value=True) + + maintenance_obj = Message( + self.class_params['sid'], + self.class_params['data'], + self.class_params['cmd'] + ) + + p = BatchProcess( + desc=maintenance_obj, + cmd=self.class_params['cmd'], + args=self.class_params['args'] + ) + + # Check that _create_process has been called + self.assertTrue(db_mock.session.add.called) + + # Check start method + self._check_start(popen_mock, p, maintenance_obj) + + # Check list method + self._check_list(p, maintenance_obj) @patch('pgadmin.misc.bgprocess.processes.Process') def _check_start(self, popen_mock, p, maintenance_obj, process_mock): diff --git a/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py index dfaf94c03..c1dce7d95 100644 --- a/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py +++ b/web/pgadmin/tools/maintenance/tests/test_maintenance_message.py @@ -28,8 +28,8 @@ class MaintenanceMessageTest(BaseTestGenerator): }, cmd="VACUUM VERBOSE;\n" ), - extected_msg="Maintenance (Vacuum)", - expetced_details_cmd='VACUUM VERBOSE;' + expected_msg="Maintenance (Vacuum)", + expected_details_cmd='VACUUM VERBOSE;' )), ('When maintained the server with FULL VERBOSE options', @@ -46,8 +46,8 @@ class MaintenanceMessageTest(BaseTestGenerator): }, cmd="VACUUM FULL VERBOSE;\n" ), - extected_msg="Maintenance (Vacuum)", - expetced_details_cmd='VACUUM FULL VERBOSE;' + expected_msg="Maintenance (Vacuum)", + expected_details_cmd='VACUUM FULL VERBOSE;' )), ('When maintained the server with ANALYZE', @@ -64,8 +64,8 @@ class MaintenanceMessageTest(BaseTestGenerator): }, cmd="ANALYZE VERBOSE;\n" ), - extected_msg="Maintenance (Analyze)", - expetced_details_cmd='ANALYZE VERBOSE;' + expected_msg="Maintenance (Analyze)", + expected_details_cmd='ANALYZE VERBOSE;' )), ('When maintained the server with REINDEX', @@ -82,8 +82,8 @@ class MaintenanceMessageTest(BaseTestGenerator): }, cmd="REINDEX;\n" ), - extected_msg="Maintenance (Reindex)", - expetced_details_cmd='REINDEX;' + expected_msg="Maintenance (Reindex)", + expected_details_cmd='REINDEX;' )), ('When maintained the server with CLUSTER', @@ -100,8 +100,8 @@ class MaintenanceMessageTest(BaseTestGenerator): }, cmd="CLUSTER VERBOSE;\n" ), - extected_msg="Maintenance (Cluster)", - expetced_details_cmd='CLUSTER VERBOSE;' + expected_msg="Maintenance (Cluster)", + expected_details_cmd='CLUSTER VERBOSE;' )), ] @@ -114,8 +114,8 @@ class MaintenanceMessageTest(BaseTestGenerator): ) # Check the expected message returned - self.assertEqual(maintenance_obj.message, self.extected_msg) + self.assertEqual(maintenance_obj.message, self.expected_msg) # Check the command obj_details = maintenance_obj.details(self.class_params['cmd'], None) - self.assertIn(self.expetced_details_cmd, obj_details) + self.assertIn(self.expected_details_cmd, obj_details) diff --git a/web/pgadmin/tools/restore/tests/test_batch_process.py b/web/pgadmin/tools/restore/tests/test_batch_process.py index 13ee5cc65..bddaeba0c 100644 --- a/web/pgadmin/tools/restore/tests/test_batch_process.py +++ b/web/pgadmin/tools/restore/tests/test_batch_process.py @@ -9,7 +9,8 @@ import sys -from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc +from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc, \ + current_app from pgadmin.tools.restore import RestoreMessage from pgadmin.utils.route import BaseTestGenerator from pickle import dumps, loads @@ -53,61 +54,61 @@ class BatchProcessTest(BaseTestGenerator): @patch('pgadmin.tools.restore.RestoreMessage.get_server_details') @patch('pgadmin.misc.bgprocess.processes.Popen') - @patch('pgadmin.misc.bgprocess.processes.current_app') @patch('pgadmin.misc.bgprocess.processes.db') @patch('pgadmin.tools.restore.current_user') @patch('pgadmin.misc.bgprocess.processes.current_user') def runTest(self, current_user_mock, current_user, db_mock, - current_app_mock, popen_mock, get_server_details_mock): - current_user.id = 1 - current_user_mock.id = 1 - current_app_mock.PGADMIN_RUNTIME = False - - def db_session_add_mock(j): - cmd_obj = loads(j.desc) - self.assertTrue(isinstance(cmd_obj, IProcessDesc)) - self.assertEqual(cmd_obj.bfile, self.class_params['bfile']) - self.assertEqual(cmd_obj.cmd, - ' --file "restore_file" ' - '--host "{0}" ' - '--port "{1}" ' - '--username "{2}" ' - '--no-password ' - '--database "{3}"'.format( - self.class_params['host'], - self.class_params['port'], - self.class_params['username'], - self.class_params['database'] - )) - - get_server_details_mock.return_value = \ - self.class_params['name'],\ - self.class_params['host'],\ - self.class_params['port'] - - db_mock.session.add.side_effect = db_session_add_mock - db_mock.session.commit = MagicMock(return_value=True) - - restore_obj = RestoreMessage( - self.class_params['sid'], - self.class_params['bfile'], - *self.class_params['args'] - ) - - p = BatchProcess( - desc=restore_obj, - cmd=self.class_params['cmd'], - args=self.class_params['args'] - ) - - # Check that _create_process has been called - self.assertTrue(db_mock.session.add.called) - - # Check start method - self._check_start(popen_mock, p, restore_obj) - - # Check list method - self._check_list(p, restore_obj) + popen_mock, get_server_details_mock): + with self.app.app_context(): + current_user.id = 1 + current_user_mock.id = 1 + current_app.PGADMIN_RUNTIME = False + + def db_session_add_mock(j): + cmd_obj = loads(j.desc) + self.assertTrue(isinstance(cmd_obj, IProcessDesc)) + self.assertEqual(cmd_obj.bfile, self.class_params['bfile']) + self.assertEqual(cmd_obj.cmd, + ' --file "restore_file" ' + '--host "{0}" ' + '--port "{1}" ' + '--username "{2}" ' + '--no-password ' + '--database "{3}"'.format( + self.class_params['host'], + self.class_params['port'], + self.class_params['username'], + self.class_params['database'] + )) + + get_server_details_mock.return_value = \ + self.class_params['name'], \ + self.class_params['host'], \ + self.class_params['port'] + + db_mock.session.add.side_effect = db_session_add_mock + db_mock.session.commit = MagicMock(return_value=True) + + restore_obj = RestoreMessage( + self.class_params['sid'], + self.class_params['bfile'], + *self.class_params['args'] + ) + + p = BatchProcess( + desc=restore_obj, + cmd=self.class_params['cmd'], + args=self.class_params['args'] + ) + + # Check that _create_process has been called + self.assertTrue(db_mock.session.add.called) + + # Check start method + self._check_start(popen_mock, p, restore_obj) + + # Check list method + self._check_list(p, restore_obj) @patch('pgadmin.misc.bgprocess.processes.Process') def _check_start(self, popen_mock, p, restore_obj, process_mock): diff --git a/web/pgadmin/tools/restore/tests/test_restore_message.py b/web/pgadmin/tools/restore/tests/test_restore_message.py index d11403dcf..e3e8bc381 100644 --- a/web/pgadmin/tools/restore/tests/test_restore_message.py +++ b/web/pgadmin/tools/restore/tests/test_restore_message.py @@ -45,9 +45,9 @@ class RestoreMessageTest(BaseTestGenerator): ], cmd="/test_path/pg_restore" ), - extected_msg="Restoring backup on the server " + expected_msg="Restoring backup on the server " "'test_restore_server (localhost:5444)'", - expetced_details_cmd='/test_path/pg_restore --file ' + expected_details_cmd='/test_path/pg_restore --file ' '"restore_file" --host "localhost"' ' --port "5444" --username "postgres" ' '--no-password --database "postgres"' @@ -69,9 +69,9 @@ class RestoreMessageTest(BaseTestGenerator): ) # Check the expected message returned - self.assertEqual(restore_obj.message, self.extected_msg) + self.assertEqual(restore_obj.message, self.expected_msg) # Check the command obj_details = restore_obj.details(self.class_params['cmd'], self.class_params['args']) - self.assertIn(self.expetced_details_cmd, obj_details) + self.assertIn(self.expected_details_cmd, obj_details) diff --git a/web/pgadmin/utils/html.py b/web/pgadmin/utils/html.py index 0cb403a84..5edb24b97 100644 --- a/web/pgadmin/utils/html.py +++ b/web/pgadmin/utils/html.py @@ -9,9 +9,13 @@ """Utilities for HTML""" -import cgi from pgadmin.utils import IS_PY2 +if IS_PY2: + from cgi import escape as html_escape +else: + from html import escape as html_escape + def safe_str(x): try: @@ -32,4 +36,4 @@ def safe_str(x): x = x.decode('utf-8') except Exception: pass - return cgi.escape(x) + return html_escape(x, False)