diff --git a/web/package.json b/web/package.json index b64bbe1..a551af1 100644 --- a/web/package.json +++ b/web/package.json @@ -87,6 +87,7 @@ "snapsvg": "^0.5.1", "spectrum-colorpicker": "^1.8.0", "sprintf-js": "^1.1.1", + "tablesorter": "^2.30.6", "underscore": "^1.8.3", "underscore.string": "^3.3.4", "watchify": "~3.9.0", diff --git a/web/pgadmin/feature_tests/xss_checks_file_manager_test.py b/web/pgadmin/feature_tests/xss_checks_file_manager_test.py index 60d7e91..68d702b 100644 --- a/web/pgadmin/feature_tests/xss_checks_file_manager_test.py +++ b/web/pgadmin/feature_tests/xss_checks_file_manager_test.py @@ -9,6 +9,7 @@ import os import time +import sys from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By @@ -21,7 +22,7 @@ class CheckFileManagerFeatureTest(BaseFeatureTest): """Tests to check file manager for XSS.""" scenarios = [ - ("Tests to check if File manager is vulnerable to XSS", + ("File manager feature test", dict()) ] @@ -55,10 +56,17 @@ class CheckFileManagerFeatureTest(BaseFeatureTest): test_utils.drop_database(connection, "acceptance_test_db") def runTest(self): + print("Tests to check if File manager is vulnerable to XSS... ", + file=sys.stderr, end="") self._navigate_to_query_tool() self.page.fill_codemirror_area_with("SELECT 1;") self._create_new_file() self._open_file_manager_and_check_xss_file() + print("OK.", file=sys.stderr) + + print("File manager sorting of data", file=sys.stderr) + self._check_file_sorting() + print("OK.", file=sys.stderr) def _navigate_to_query_tool(self): self.page.toggle_open_tree_item(self.server['name']) @@ -124,3 +132,32 @@ class CheckFileManagerFeatureTest(BaseFeatureTest): assert source_code.find( string_to_find ) != -1, "{0} might be vulnerable to XSS ".format(source) + + def _check_file_sorting(self): + self.page.find_by_id("btn-load-file").click() + self.wait.until( + EC.element_to_be_clickable(( + By.CSS_SELECTOR, + "#contents th[data-column='0']") + ) + ) + + # Added time.sleep so that the element to be clicked. + time.sleep(0.05) + self.page.find_by_css_selector("#contents th[data-column='0']").click() + # Check for sort Ascending + self.wait.until( + EC.presence_of_element_located(( + By.CSS_SELECTOR, + "#contents th[data-column='0'].tablesorter-headerAsc") + ) + ) + + # Click and Check for sort Descending + self.page.find_by_css_selector("#contents th[data-column='0']").click() + self.wait.until( + EC.presence_of_element_located(( + By.CSS_SELECTOR, + "#contents th[data-column='0'].tablesorter-headerDesc") + ) + ) diff --git a/web/pgadmin/misc/file_manager/static/css/file_manager.css b/web/pgadmin/misc/file_manager/static/css/file_manager.css index 6e4ee9e..6e76795 100644 --- a/web/pgadmin/misc/file_manager/static/css/file_manager.css +++ b/web/pgadmin/misc/file_manager/static/css/file_manager.css @@ -233,17 +233,6 @@ div.clip { color: #fff; } -.file_listing #contents.list th.tablesorter-headerAsc, -.file_listing #contents.list th.tablesorter-headerDesc { - background: rgb(214,212,209); /* Old browsers */ - background: -moz-linear-gradient(top, rgba(214,212,209,1) 0%, rgba(244,241,237,1) 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(214,212,209,1)), color-stop(100%,rgba(244,241,237,1))); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, rgba(214,212,209,1) 0%,rgba(244,241,237,1) 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, rgba(214,212,209,1) 0%,rgba(244,241,237,1) 100%); /* Opera 11.10+ */ - background: -ms-linear-gradient(top, rgba(214,212,209,1) 0%,rgba(244,241,237,1) 100%); /* IE10+ */ - background: linear-gradient(to bottom, rgba(214,212,209,1) 0%,rgba(244,241,237,1) 100%); /* W3C */ -} - .file_listing #contents.list td:first-child { display: table-cell; padding-left: 0; @@ -729,3 +718,43 @@ a.dz-remove { div.change_file_types span { padding-left:10px; } + +/* overall */ +.tablesorter .header, +.tablesorter .tablesorter-header { + /* black (unsorted) double arrow */ + background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); + background-repeat: no-repeat; + background-position: center right; + padding: 4px 18px 4px 4px; + white-space: normal; + cursor: pointer; +} + +.tablesorter .headerSortUp, +.tablesorter .tablesorter-headerSortUp, +.tablesorter .tablesorter-headerAsc { + /* black asc arrow */ + background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); +} + +.tablesorter .headerSortDown, +.tablesorter .tablesorter-headerSortDown, +.tablesorter .tablesorter-headerDesc { + /* black desc arrow */ + background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); +} + +.tablesorter thead .sorter-false { + background-image: none; + cursor: default; + padding: 4px; +} + +/* table processing indicator */ +.tablesorter .tablesorter-processing { + background-position: center center !important; + background-repeat: no-repeat !important; + background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important; +} + diff --git a/web/pgadmin/misc/file_manager/static/js/utility.js b/web/pgadmin/misc/file_manager/static/js/utility.js index ce3cd17..ef62aba 100644 --- a/web/pgadmin/misc/file_manager/static/js/utility.js +++ b/web/pgadmin/misc/file_manager/static/js/utility.js @@ -13,6 +13,7 @@ import loading_icon from 'acitree/image/load-root.gif'; define([ 'jquery', 'underscore', 'underscore.string', 'pgadmin.alertifyjs', 'sources/gettext', 'sources/url_for', 'dropzone', 'sources/pgadmin', + 'tablesorter', ], function($, _, S, Alertify, gettext, url_for, Dropzone, pgAdmin) { /*--------------------------------------------------------- @@ -574,8 +575,8 @@ define([ result += ''; } else { - result += ''; - result += '
'; + result += ''; + result += ''; result += ''; @@ -649,8 +650,8 @@ define([ if ($('.fileinfo').data('view') == 'grid') { result += '
    '; } else { - result += '
    '; result += '' + lg.name + '' + lg.size + ''; result += '' + lg.modified + '
    '; - result += '
    ' + + result += ''; + result += ''; @@ -667,6 +668,7 @@ define([ // Add the new markup to the DOM. $('.fileinfo .file_listing').html(result); + $('.fileinfo .file_listing #contents').tablesorter(); // rename file/folder $('.file_manager button.rename').off().on('click', function(e) {
    ' + lg.name + '' + lg.size + '' + lg.modified + '