Hi Dave,
Please find updated attached patch for RM1911 (V2)
--
*Harshal Dhumal*
*Software Engineer*
EnterpriseDB India: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
On Mon, Nov 21, 2016 at 7:48 PM, Dave Page <[email protected]> wrote:
> Hi
>
> On Sat, Nov 19, 2016 at 5:57 PM, Harshal Dhumal
> <[email protected]> wrote:
> > Hi,
> >
> > PFA for RM1911
> >
> > Feature added: Allow user add file/folder path directly in input field.
> > Other improvements like clean up after file manager is closed.
>
> I did a quick check on Mac, in server mode and immediately hit problems:
>
> - [Screenshot 1]: I typed in "/Foo2" to navigate into the Foo2
> directory. a) it didn't navigate as expected, and b) it gave me a very
> non-user friendly error message.
>
> Fixed.
> - [Screenshot 2]: I typed in "foo2.sql". It added the leading /
> automatically, then gave the error dpagefoo2.sql does not exist.
>
> Fixed.
> Then on Windows in desktop mode:
>
> - [Screenshot 3]: I typed in "C:\Users\dpage" (which does exist) and
> got the error shown.
>
> Fixed.
> - [Screenshot 4]: I typed in "\\172.16.253.235\data" (which does
> exist) and got the error shown.
>
Fixed.
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>
diff --git a/web/pgadmin/misc/file_manager/__init__.py b/web/pgadmin/misc/file_manager/__init__.py
index 4a8e709..74f37fc 100644
--- a/web/pgadmin/misc/file_manager/__init__.py
+++ b/web/pgadmin/misc/file_manager/__init__.py
@@ -15,6 +15,7 @@ import random
import string
import time
from sys import platform as _platform
+import config
import simplejson as json
from flask import render_template, Response, session, request as req, url_for
@@ -244,12 +245,12 @@ class Filemanager(object):
{
'Error': gettext('No permission to operate on \
specified path.'),
- 'Code': -1
+ 'Code': 0
}
)
self.dir = get_storage_directory()
- if (self.dir is not None and isinstance(self.dir, list)):
+ if self.dir is not None and isinstance(self.dir, list):
self.dir = ""
@staticmethod
@@ -403,6 +404,20 @@ class Filemanager(object):
It lists all file and folders within the given
directory.
"""
+ if dir is None:
+ dir = ""
+ try:
+ Filemanager.check_access_permission(dir, path)
+ except Exception as e:
+ err_msg = "Error: {0}".format(str(e))
+ files = {
+ 'Code': 0,
+ 'Error': err_msg
+ }
+ return files
+
+ orig_path = "{0}{1}".format(dir, path)
+
files = {}
if (_platform == "win32" and path == '/') and dir is None:
drives = Filemanager._get_drives()
@@ -428,9 +443,6 @@ class Filemanager(object):
}
return files
- if dir is None:
- dir = ""
- orig_path = "{0}{1}".format(dir, path)
user_dir = path
folders_only = trans_data['folders_only'] if 'folders_only' in \
trans_data else ''
@@ -447,7 +459,7 @@ class Filemanager(object):
system_path = os.path.join(os.path.join(orig_path, f))
# continue if file/folder is hidden
- if (is_folder_hidden(system_path) or f.startswith('.')):
+ if is_folder_hidden(system_path) or f.startswith('.'):
continue
user_path = os.path.join(os.path.join(user_dir, f))
@@ -494,10 +506,27 @@ class Filemanager(object):
err_msg = "Error: {0}".format(e)
files = {
'Code': 0,
- 'err_msg': err_msg
+ 'Error': err_msg
}
return files
+ @staticmethod
+ def check_access_permission(dir, path):
+ if dir is None:
+ dir = ""
+ orig_path = "{0}{1}".format(dir, path)
+
+ # This translates path with relative path notations like ./ and ../ to
+ # absolute path.
+ orig_path = os.path.abspath(orig_path)
+
+ # Do not allow user to access outside his storage dir in server mode.
+ if config.SERVER_MODE is True:
+ if not orig_path.startswith(dir):
+ raise Exception(
+ gettext("Access denied ({})".format(orig_path)))
+ return True
+
def validate_request(self, capability):
"""
It validates the capability with the capabilities
@@ -515,14 +544,37 @@ class Filemanager(object):
path = unquote(path)
if self.dir is None:
self.dir = ""
+
+ try:
+ Filemanager.check_access_permission(self.dir, path)
+ except Exception as e:
+ thefile = {
+ 'Filename': split_path(path)[-1],
+ 'FileType': '',
+ 'Path': path,
+ 'Error': gettext("Error: {0}".format(str(e))),
+ 'Code': 0,
+ 'Info': '',
+ 'Properties': {
+ 'Date Created': '',
+ 'Date Modified': '',
+ 'Width': '',
+ 'Height': '',
+ 'Size': ''
+ }
+ }
+ return thefile
+
orig_path = "{0}{1}".format(self.dir, path)
+
user_dir = path
thefile = {
'Filename': split_path(orig_path)[-1],
- 'File Type': '',
+ 'FileType': '',
'Path': user_dir,
'Error': '',
- 'Code': 0,
+ 'Code': 1,
+ 'Info': '',
'Properties': {
'Date Created': '',
'Date Modified': '',
@@ -533,13 +585,16 @@ class Filemanager(object):
}
if not path_exists(orig_path):
- thefile['Error'] = gettext('File does not exist.')
- return (encode_json(thefile), None, 'application/json')
-
- if split_path(user_dir)[-1] == '/':
- thefile['File Type'] = 'Directory'
+ thefile['Error'] = gettext("'{}' file does not exist.".format(
+ split_path(orig_path)[-1]))
+ thefile['Code'] = -1
+ return thefile
+
+ if split_path(user_dir)[-1] == '/'\
+ or os.path.isfile(orig_path) is False:
+ thefile['FileType'] = 'Directory'
else:
- thefile['File Type'] = splitext(user_dir)
+ thefile['FileType'] = splitext(user_dir)
created = time.ctime(os.path.getctime(orig_path))
modified = time.ctime(os.path.getmtime(orig_path))
@@ -566,10 +621,21 @@ class Filemanager(object):
if not self.validate_request('rename'):
return {
'Error': gettext('Not allowed'),
- 'Code': 1
+ 'Code': 0
}
dir = self.dir if self.dir is not None else ''
+
+ try:
+ Filemanager.check_access_permission(dir, old)
+ Filemanager.check_access_permission(dir, new)
+ except Exception as e:
+ res = {
+ 'Error': gettext("Error: {0}".format(str(e))),
+ 'Code': 0
+ }
+ return res
+
# check if it's dir
if old[-1] == '/':
old = old[:-1]
@@ -594,8 +660,8 @@ class Filemanager(object):
code = 1
try:
os.rename(oldpath_sys, newpath_sys)
- code = 0
except Exception as e:
+ code = 0
error_msg = "{0} {1}".format(
gettext('There was an error renaming the file:'),
str(e))
@@ -618,10 +684,20 @@ class Filemanager(object):
if not self.validate_request('delete'):
return {
'Error': gettext('Not allowed'),
- 'Code': 1
+ 'Code': 0
}
dir = self.dir if self.dir is not None else ''
+
+ try:
+ Filemanager.check_access_permission(dir, path)
+ except Exception as e:
+ res = {
+ 'Error': gettext("Error: {0}".format(str(e))),
+ 'Code': 0
+ }
+ return res
+
orig_path = "{0}{1}".format(dir, path)
err_msg = ''
@@ -629,11 +705,10 @@ class Filemanager(object):
try:
if os.path.isdir(orig_path):
os.rmdir(orig_path)
- code = 0
else:
os.remove(orig_path)
- code = 0
except Exception as e:
+ code = 0
err_msg = "Error: {0}".format(e.strerror)
result = {
@@ -651,7 +726,7 @@ class Filemanager(object):
if not self.validate_request('upload'):
return {
'Error': gettext('Not allowed'),
- 'Code': 1
+ 'Code': 0
}
dir = self.dir if self.dir is not None else ''
@@ -665,10 +740,19 @@ class Filemanager(object):
with open(newName, 'wb') as f:
f.write(thefile.read())
- code = 0
except Exception as e:
+ code = 0
err_msg = "Error: {0}".format(e.strerror)
+ try:
+ Filemanager.check_access_permission(dir, path)
+ except Exception as e:
+ res = {
+ 'Error': gettext("Error: {0}".format(str(e))),
+ 'Code': 0
+ }
+ return res
+
result = {
'Path': path,
'Name': newName,
@@ -687,13 +771,17 @@ class Filemanager(object):
name = unquote(name)
try:
orig_path = "{0}{1}".format(dir, path)
+ Filemanager.check_access_permission(dir, "{}{}".format(path, name))
+
newName = '{0}{1}'.format(orig_path, name)
- if os.path.exists(newName):
+ if not os.path.exists(newName):
code = 0
- else:
- code = 1
except Exception as e:
- err_msg = "Error: {0}".format(e.strerror)
+ code = 0
+ if hasattr(e, 'strerror'):
+ err_msg = "Error: {0}".format(e.strerror)
+ else:
+ err_msg = "Error: {0}".format(str(e))
result = {
'Path': path,
@@ -730,11 +818,22 @@ class Filemanager(object):
if not self.validate_request('create'):
return {
'Error': gettext('Not allowed'),
- 'Code': 1
+ 'Code': 0
}
dir = self.dir if self.dir is not None else ''
newName = name
+
+ try:
+ Filemanager.check_access_permission(dir, "{}{}".format(
+ path, newName))
+ except Exception as e:
+ res = {
+ 'Error': gettext("Error: {0}".format(str(e))),
+ 'Code': 0
+ }
+ return res
+
if dir != "":
newPath = dir + '/' + path + newName + '/'
else:
@@ -745,15 +844,15 @@ class Filemanager(object):
if not path_exists(newPath):
try:
os.mkdir(newPath)
- code = 0
except Exception as e:
+ code = 0
err_msg = "Error: {0}".format(e.strerror)
else:
newPath, newName = self.getNewName(dir, path, newName)
try:
os.mkdir(newPath)
- code = 0
except Exception as e:
+ code = 0
err_msg = "Error: {0}".format(e.strerror)
result = {
@@ -772,10 +871,19 @@ class Filemanager(object):
if not self.validate_request('download'):
return {
'Error': gettext('Not allowed'),
- 'Code': 1
+ 'Code': 0
}
dir = self.dir if self.dir is not None else ''
+
+ try:
+ Filemanager.check_access_permission(dir, "{}{}".format(
+ path, path))
+ except Exception as e:
+ resp = Response(gettext("Error: {0}".format(str(e))))
+ resp.headers['Content-Disposition'] = 'attachment; filename=' + name
+ return resp
+
orig_path = "{0}{1}".format(dir, path)
name = path.split('/')[-1]
content = open(orig_path, 'r')
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 ea502ac..56d9c38 100755
--- a/web/pgadmin/misc/file_manager/static/css/file_manager.css
+++ b/web/pgadmin/misc/file_manager/static/css/file_manager.css
@@ -15,19 +15,17 @@
top: 35px;
}
-#uploader h1 {
+#uploader .input-path {
font-size: 14px;
margin: 0;
- margin-left: 5px;
padding: 0;
display: block;
float: left;
text-align: left;
- line-height:1.9em;
- max-width: 367px;
+ line-height:1.6em;
+ width: calc(100% - 72px);
text-overflow: ellipsis;
overflow: hidden;
- color: #999;
}
#uploader h1 b {
diff --git a/web/pgadmin/misc/file_manager/templates/file_manager/index.html b/web/pgadmin/misc/file_manager/templates/file_manager/index.html
index 197386f..992fe5d 100755
--- a/web/pgadmin/misc/file_manager/templates/file_manager/index.html
+++ b/web/pgadmin/misc/file_manager/templates/file_manager/index.html
@@ -5,13 +5,14 @@
</head>
<body>
<div class="file_manager">
- <form id="uploader" method="post" class='col-xs-12'>
+ <div id="uploader" class='col-xs-12'>
<div class="btn-group filemanager-path-group col-sm-7 col-xs-12" role="group">
<button name="home" type="button" value="Home" title="Home" class="fa fa-home btn home"><span></span>
</button>
<button name="level-up" type="button" title="Back" value="LevelUp" class="btn fa fa-level-up level-up"
disabled><span></span></button>
- <h1 title=''></h1>
+ <input class='input-path' title='' type="text"/>
+
</div>
<div class="btn-group filemanager-btn-group" role="group">
<div class="uploadresponse"></div>
@@ -29,7 +30,7 @@
<button class="ON fa fa-th btn grid" type="button" title="View as grid"><span></span></button>
<button type="button" class="btn fa fa-list list" title="View as Table"><span></span></button>
</div>
- </form>
+ </div>
<div class="fileinfo">
<span class="activity">
<img src="{{ url_for('browser.static', filename='css/aciTree/image/load-root.gif') }}">
diff --git a/web/pgadmin/misc/file_manager/templates/file_manager/js/file_manager.js b/web/pgadmin/misc/file_manager/templates/file_manager/js/file_manager.js
index 473a05f..0410337 100644
--- a/web/pgadmin/misc/file_manager/templates/file_manager/js/file_manager.js
+++ b/web/pgadmin/misc/file_manager/templates/file_manager/js/file_manager.js
@@ -81,6 +81,7 @@ define([
return {
main: function(params) {
// Set title and button name
+ var self = this;
if (_.isUndefined(params['dialog_title'])) {
params['dialog_title'] = 'Storage manager';
}
@@ -96,6 +97,9 @@ define([
renderStoragePanel(params);
this.elements.dialog.style.minWidth = '630px';
this.show();
+ $($container.find('.file_manager')).on('enter-key', function() {
+ $($(self.elements.footer).find('.file_manager_ok')).trigger('click')
+ });
},
settings: {
label: undefined
@@ -133,19 +137,18 @@ define([
},
callback: function(closeEvent) {
if (closeEvent.button.text == "{{ _('Select') }}") {
- if($('.fileinfo').data('view') == 'grid') {
- sel_file = $('.fileinfo').find('#contents li.selected p span').attr('title');
- } else {
- sel_file = $('.fileinfo tbody tr.selected td p span').attr('title');
- }
- var newFile = $('.currentpath').val() + sel_file;
+ var newFile = $('.storage_dialog #uploader .input-path').val();
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:storage_dialog', newFile);
+ var innerbody = $(this.elements.body).find('.storage_content')
+ $(innerbody).find('*').off();
+ innerbody.remove();
+ removeTransId(trans_id);
} else if (closeEvent.button.text == "{{ _('Cancel') }}") {
- if (removeTransId(trans_id)) {
- this.destroy();
- return;
- }
+ var innerbody = $(this.elements.body).find('.storage_content')
+ $(innerbody).find('*').off();
+ innerbody.remove();
+ removeTransId(trans_id);
}
},
build: function() {
@@ -195,6 +198,7 @@ define([
return {
main: function(params) {
// Set title and button name
+ var self = this;
if (_.isUndefined(params['dialog_title'])) {
params['dialog_title'] = 'Select file';
}
@@ -210,6 +214,9 @@ define([
renderStoragePanel(params);
this.elements.dialog.style.minWidth = '630px';
this.show();
+ $($container.find('.file_manager')).on('enter-key', function() {
+ $($(self.elements.footer).find('.file_manager_ok')).trigger('click')
+ });
},
settings: {
label: undefined
@@ -249,20 +256,18 @@ define([
},
callback: function(closeEvent) {
if (closeEvent.button.text == "{{ _('Select') }}") {
- if($('.fileinfo').data('view') == 'grid') {
- sel_file = $('.fileinfo').find('#contents li.selected p span').attr('title');
- } else {
- sel_file = $('.fileinfo tbody tr.selected td p span').attr('title');
- }
- var newFile = $('.currentpath').val() + sel_file;
+ var newFile = $('.storage_dialog #uploader .input-path').val();
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:select_file', newFile);
+ var innerbody = $(this.elements.body).find('.storage_content')
+ $(innerbody).find('*').off();
+ innerbody.remove();
removeTransId(trans_id);
} else if (closeEvent.button.text == "{{ _('Cancel') }}") {
- if (removeTransId(trans_id)) {
- this.destroy();
- return;
- }
+ var innerbody = $(this.elements.body).find('.storage_content')
+ $(innerbody).find('*').off();
+ innerbody.remove();
+ removeTransId(trans_id);
}
},
build: function() {
@@ -311,6 +316,7 @@ define([
// Dialog property
return {
main: function(params) {
+ var self = this;
// Set title and button name
if (_.isUndefined(params['dialog_title'])) {
params['dialog_title'] = 'Select folder';
@@ -327,6 +333,9 @@ define([
renderStoragePanel(params);
this.elements.dialog.style.minWidth = '630px';
this.show();
+ $($container.find('.file_manager')).on('enter-key', function() {
+ $($(self.elements.footer).find('.file_manager_ok')).trigger('click')
+ });
},
settings: {
label: undefined
@@ -366,20 +375,18 @@ define([
},
callback: function(closeEvent) {
if (closeEvent.button.text == "{{ _('Select') }}") {
- if($('.fileinfo').data('view') == 'grid') {
- sel_file = $('.fileinfo').find('#contents li.selected p span').attr('title');
- } else {
- sel_file = $('.fileinfo tbody tr.selected td p span').attr('title');
- }
- var newFile = $('.currentpath').val() + sel_file;
+ var newFile = $('.storage_dialog #uploader .input-path').val();
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:select_folder', newFile);
+ var innerbody = $(this.elements.body).find('.storage_content')
+ $(innerbody).find('*').off();
+ innerbody.remove();
removeTransId(trans_id);
} else if (closeEvent.button.text == "{{ _('Cancel') }}") {
- if (removeTransId(trans_id)) {
- this.destroy();
- return;
- }
+ var innerbody = $(this.elements.body).find('.storage_content')
+ $(innerbody).find('*').off();
+ innerbody.remove();
+ removeTransId(trans_id);
}
},
build: function() {
@@ -427,7 +434,8 @@ define([
// Dialog property
return {
main: function(params) {
- var trans_id;
+ var self = this,
+ trans_id;
// Set title and button name
if (_.isUndefined(params['dialog_title'])) {
params['dialog_title'] = 'Create file';
@@ -444,6 +452,9 @@ define([
renderStoragePanel(params);
this.elements.dialog.style.minWidth = '630px';
this.show();
+ $($container.find('.file_manager')).on('enter-key', function() {
+ $($(self.elements.footer).find('.file_manager_ok')).trigger('click')
+ });
},
settings: {
label: undefined
@@ -485,8 +496,7 @@ define([
$('.replace_file, .fm_dimmer').show();
$('.replace_file .btn_yes').click(function(self) {
$('.replace_file, .fm_dimmer').hide();
- var selected_item = $('.allowed_file_types .create_input input[type="text"]').val(),
- newFile = $('.currentpath').val() + selected_item;
+ var newFile = $('.storage_dialog #uploader .input-path').val()
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:create_file', newFile);
$('.file_manager_create_cancel').trigger('click');
@@ -496,11 +506,13 @@ define([
});
},
is_file_exist: function() {
- var selected_item = $('.allowed_file_types .create_input input[type="text"]').val(),
+ var full_path = $('.storage_dialog #uploader .input-path').val(),
+ path = full_path.substr(0, full_path.lastIndexOf('/') + 1),
+ selected_item = full_path.substr(full_path.lastIndexOf('/') + 1),
is_exist = false;
var file_data = {
- 'path': $('.currentpath').val(),
+ 'path': path,
'name': selected_item,
'mode': 'is_file_exist'
};
@@ -514,7 +526,7 @@ define([
async: false,
success: function(resp) {
data = resp.data.result;
- if(data['Code'] === 0) {
+ if(data['Code'] === 1) {
is_exist = true;
} else {
is_exist = false;
@@ -525,22 +537,23 @@ define([
},
callback: function(closeEvent) {
if (closeEvent.button.text == "{{ _('Create') }}") {
- var selected_item = $('.allowed_file_types .create_input input[type="text"]').val();
- var newFile = $('.currentpath').val() + selected_item;
+ var newFile = $('.storage_dialog #uploader .input-path').val();
- if(!_.isUndefined(selected_item) && selected_item !== '' && this.is_file_exist()) {
+ if(!_.isUndefined(newFile) && newFile !== '' && this.is_file_exist()) {
this.replace_file();
closeEvent.cancel = true;
- }
- else {
+ } else {
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:create_file', newFile);
+ var innerbody = $(this.elements.body).find('.storage_content')
+ $(innerbody).find('*').off();
+ innerbody.remove();
removeTransId(trans_id);
}
} else if (closeEvent.button.text == "{{ _('Cancel') }}") {
- if (removeTransId(trans_id)) {
- this.destroy();
- return;
- }
+ var innerbody = $(this.elements.body).find('.storage_content')
+ $(innerbody).find('*').off();
+ innerbody.remove();
+ removeTransId(trans_id);
}
},
build: function() {
diff --git a/web/pgadmin/misc/file_manager/templates/file_manager/js/utility.js b/web/pgadmin/misc/file_manager/templates/file_manager/js/utility.js
index f1a5ef4..b0aadc2 100755
--- a/web/pgadmin/misc/file_manager/templates/file_manager/js/utility.js
+++ b/web/pgadmin/misc/file_manager/templates/file_manager/js/utility.js
@@ -188,7 +188,7 @@ var hideButtons = function() {
* to the path specified. Called on initial page load and
* whenever a new directory is selected.
*/
-var setUploader = function(path) {
+var setUploader = function(path, type) {
$('.storage_dialog #uploader').find('a').remove();
$('.storage_dialog #uploader').find('b').remove();
@@ -213,15 +213,20 @@ var setUploader = function(path) {
Object.keys(split_path).forEach(function (i) {
file_path += split_path[i] + '/';
});
- $('.storage_dialog #uploader h1').html(file_path);
+
+ if (type == 'file' && file_path.charAt(file_path.length - 1) == '/') {
+ file_path = file_path.substring(0, file_path.length - 1);
+ path = file_path.substr(0, file_path.lastIndexOf('/') + 1);
+ }
+ $('.storage_dialog #uploader .input-path').val(file_path);
$('.currentpath').val(path);
if ($('.storage_dialog #uploader h1 span').length === 0) {
$('<span>'+lg.current_folder+'</span>').appendTo($('.storage_dialog #uploader h1'));
}
- $('.storage_dialog #uploader h1').attr('title', display_string);
- $('.storage_dialog #uploader h1').attr('data-path', display_string);
+ $('.storage_dialog #uploader .input-path').attr('title', display_string);
+ $('.storage_dialog #uploader .input-path').attr('data-path', display_string);
// create new folder
$('.create').unbind().click(function() {
@@ -320,7 +325,7 @@ var setUploader = function(path) {
var d = new Date(); // to prevent IE cache issues
$.getJSON(fileConnector + '?mode=addfolder&path=' + $('.currentpath').val() + '&name=' + foldername, function(resp) {
var result = resp.data.result;
- if (result.Code === 0) {
+ if (result.Code === 1) {
alertify.success(lg.successful_added_folder);
getFolderInfo(result.Parent);
} else {
@@ -414,7 +419,6 @@ var enable_disable_btn = function() {
$('.file_manager').find('button.download').prop('disabled', true);
$('.file_manager').find('button.rename').prop('disabled', true);
if ($grid_file.length > 0) {
- $('.create_input input[type="text"]').val('');
$('.file_manager_ok').addClass('disabled');
}
} else {
@@ -424,14 +428,13 @@ var enable_disable_btn = function() {
$('.file_manager').find('button.download').prop('disabled', true);
$('.file_manager').find('button.rename').prop('disabled', true);
if ($list_file.length > 0) {
- $('.create_input input[type="text"]').val('');
$('.file_manager_ok').addClass('disabled');
}
}
$('.delete_item').hide();
// clear address bar
- $('.file_manager #uploader h1').show();
+ $('.file_manager #uploader .input-path').show();
$('.file_manager #uploader .show_selected_file').remove();
};
@@ -468,7 +471,7 @@ var renameItem = function(data) {
async: false,
success: function(resp) {
var result = resp.data.result;
- if (result.Code === 0) {
+ if (result.Code === 1) {
var newPath = result['New Path'],
newName = result['New Name'],
title = $("#preview h1").attr("title");
@@ -532,7 +535,7 @@ var deleteItem = function(data) {
async: false,
success: function(resp) {
var result = resp.data.result;
- if (result.Code === 0) {
+ if (result.Code === 1) {
isDeleted = true;
if (isDeleted) {
alertify.success(lg.successful_delete);
@@ -580,11 +583,11 @@ var getDetailView = function(path) {
*/
var getFileInfo = function(file) {
// Update location for status, upload, & new folder functions.
- var currentpath = file.substr(0, file.lastIndexOf('/') + 1);
- setUploader(currentpath);
+ setUploader(file, 'file');
// Retrieve the data & populate the template.
- var d = new Date(); // to prevent IE cache issues
+ var d = new Date(), // to prevent IE cache issues
+ is_file_valid = false;
var post_data = {
'path': file,
'mode': 'getinfo'
@@ -599,8 +602,8 @@ var getFileInfo = function(file) {
async: false,
success: function(resp) {
var data = resp.data.result;
-
- if (data.Code === 0) {
+ if (data.Code === 1) {
+ $('.file_manager_ok').removeClass('disabled');
var properties = '';
if (
data.Properties.Size || parseInt(data.Properties.Size)==0
@@ -611,11 +614,24 @@ var getFileInfo = function(file) {
}
data.Capabilities = capabilities;
bindToolbar(data);
+ if (data.FileType == 'Directory') {
+ // Enable/Disable level up button
+ enab_dis_level_up();
+ $('.file_manager_ok').addClass('disabled');
+
+ $('.file_manager button.delete, .file_manager button.rename').attr('disabled', 'disabled');
+ $('.file_manager button.download').attr('disabled', 'disabled');
+ getFolderInfo(file);
+ } else {
+ is_file_valid = true;
+ }
} else {
+ $('.file_manager_ok').addClass('disabled');
alertify.error(data.Error);
}
}
});
+ return is_file_valid;
};
/*
@@ -623,11 +639,12 @@ var getFileInfo = function(file) {
* creates a list view.
*/
var getFolderInfo = function(path, file_type) {
+ $('.storage_dialog #uploader .input-path').prop('disabled', true);
if (!file_type) {
file_type = '';
}
// Update location for status, upload, & new folder functions.
- setUploader(path);
+ setUploader(path, 'dir');
// set default selected file type
if (file_type === '') {
@@ -672,16 +689,16 @@ var getFolderInfo = function(path, file_type) {
contentType: "application/json; charset=utf-8",
async: false,
success: function(resp) {
+ $('.storage_dialog #uploader .input-path').prop('disabled', false);
var result = '',
data = resp.data.result;
// hide activity indicator
$('.fileinfo').find('span.activity').hide();
if (data.Code === 0) {
- alertify.error(data.err_msg);
+ alertify.error(data.Error);
return;
}
-
// generate HTML for files/folder and render into container
if (!_.isEmpty(data)) {
if ($('.fileinfo').data('view') == 'grid') {
@@ -1038,15 +1055,11 @@ var getFolderInfo = function(path, file_type) {
if (path.lastIndexOf("/") == path.length - 1) {
$('.file_manager_ok').addClass('disabled');
- var $create_input = $('.create_input input[type="text"]');
-
$('.file_manager button.delete, .file_manager button.rename').attr('disabled', 'disabled');
$('.file_manager button.download').attr('disabled', 'disabled');
getFolderInfo(path);
- if ($create_input.length != 0 && $create_input.val() != '') {
- $('.file_manager_ok').removeClass('disabled');
- }
+
} else {
getFileInfo(path);
}
@@ -1076,7 +1089,7 @@ var getFolderInfo = function(path, file_type) {
'disabled', 'disabled'
);
// set selected folder name in breadcrums
- $('.file_manager #uploader h1').hide();
+ $('.file_manager #uploader .input-path').hide();
$('.file_manager #uploader .show_selected_file').remove();
$('<span class="show_selected_file">'+path+'</span>').appendTo(
'.file_manager #uploader .filemanager-path-group'
@@ -1097,13 +1110,6 @@ var getFolderInfo = function(path, file_type) {
$('.file_manager #uploader .show_selected_file').remove();
}
- if (
- config.options.dialog_type == 'create_file' &&
- is_protected == undefined
- ) {
- $('.create_input input[type="text"]').val(file_name);
- $('.file_manager_ok, .file_manager_create').removeClass('disabled');
- }
getFileInfo(path);
}
});
@@ -1127,7 +1133,7 @@ var getFolderInfo = function(path, file_type) {
$('.file_manager button.delete, .file_manager button.rename').removeAttr('disabled');
// set selected folder name in breadcrums
- $('.file_manager #uploader h1').hide();
+ $('.file_manager #uploader .input-path').hide();
$('.file_manager #uploader .show_selected_file').remove();
$('<span class="show_selected_file">'+path+'</span>').appendTo(
'.file_manager #uploader .filemanager-path-group'
@@ -1137,27 +1143,19 @@ var getFolderInfo = function(path, file_type) {
if (has_capability(data_cap, 'select_file') && is_protected == undefined) {
$(this).parent().find('tr.selected').removeClass('selected');
$('td:first-child', this).parent().addClass('selected');
- $('.file_manager_ok').removeClass('disabled');
$('.file_manager button.delete, .file_manager button.download, .file_manager button.rename').removeAttr(
'disabled'
);
// set selected folder name in breadcrums
$('.file_manager #uploader .show_selected_file').remove();
}
- if (
- config.options.dialog_type == 'create_file' &&
- is_protected == undefined
- ) {
- $('.create_input input[type="text"]').val(file_name);
- $('.file_manager_ok, .file_manager_create').removeClass('disabled');
- }
+
getFileInfo(path);
}
});
$('.fileinfo table#contents tbody tr').on('dblclick', function(e) {
e.stopPropagation();
-
// Enable/Disable level up button
enab_dis_level_up();
@@ -1174,13 +1172,17 @@ var getFolderInfo = function(path, file_type) {
});
}
+ input_object.set_cap(data_cap);
+ },
+ error: function() {
+ $('.storage_dialog #uploader .input-path').prop('disabled', false);
}
});
};
// Enable/Disable level up button
var enab_dis_level_up = function() {
- $('.file_manager #uploader h1').show();
+ $('.file_manager #uploader .input-path').show();
$('.show_selected_file').remove();
setTimeout(function() {
@@ -1235,6 +1237,7 @@ var fileRoot = config.options.fileRoot,
* Get localized messages from file
* through culture var or from URL
*/
+
var lg = [],
enjs = '{{ url_for("file_manager.index") }}' + "en.js",
lgf = loadData(enjs);
@@ -1292,23 +1295,6 @@ if (
});
}
-if (config.options.dialog_type == 'create_file') {
- var create_file_html = '<div class="create_input">'+
- '<span>Filename:</span>'+
- '<input type="text" name="new_filename" class="fm_create_input form-control" />'+
- '</div>';
-
- $('.create_mode_dlg').find('.allowed_file_types').prepend(create_file_html);
- $('.create_input input[type="text"]').on('keypress, keydown', function() {
- var input_text_len = $(this).val().length;
- if (input_text_len > 0 ) {
- $('.file_manager_ok').removeClass('disabled');
- } else {
- $('.file_manager_ok').addClass('disabled');
- }
- });
-}
-
/*---------------------------------------------------------
Item Actions - Object events
---------------------------------------------------------*/
@@ -1406,14 +1392,101 @@ $('.file_manager .list').click(function() {
});
// Provide initial values for upload form, status, etc.
-setUploader(fileRoot);
-
-$('#uploader').attr('action', fileConnector);
+setUploader(fileRoot, 'dir');
var data = {
'Capabilities': capabilities
};
+function InputObject() {
+ this.init= function(cap) {
+ var self = this,
+ check_obj = function(path, check) {
+
+ var path = decodeURI(path);
+
+ if (path.lastIndexOf('/') == path.length - 1) {
+ if (
+ has_capability(self.data_cap, 'select_folder')
+ ) {
+ $('.file_manager_ok').removeClass('disabled');
+ $('.file_manager button.delete, .file_manager button.rename').removeAttr(
+ 'disabled', 'disabled'
+ );
+ $('.file_manager button.download').attr(
+ 'disabled', 'disabled'
+ );
+ // set selected folder name in breadcrums
+ $('.file_manager #uploader .input-path').hide();
+ $('.file_manager #uploader .show_selected_file').remove();
+ $('<span class="show_selected_file">'+path+'</span>').appendTo(
+ '.file_manager #uploader .filemanager-path-group'
+ );
+ } else {
+ if(check) {
+ // Enable/Disable level up button
+ enab_dis_level_up();
+ $('.file_manager_ok').addClass('disabled');
+
+ $('.file_manager button.delete, .file_manager button.rename').attr('disabled', 'disabled');
+ $('.file_manager button.download').attr('disabled', 'disabled');
+ getFolderInfo(path);
+ }
+ }
+ } else {
+ if (
+ has_capability(self.data_cap, 'select_file')
+ ) {
+ $('.file_manager_ok').removeClass('disabled');
+ $('.file_manager button.delete, .file_manager button.download, .file_manager button.rename').removeAttr(
+ 'disabled'
+ );
+ // set selected folder name in breadcrums
+ $('.file_manager #uploader .show_selected_file').remove();
+ }
+
+ if(check) {
+ if (config.options.dialog_type == 'create_file') {
+ $('.file_manager').trigger('enter-key');
+ return;
+ }
+ if(config.options.dialog_type == 'select_file') {
+ var file_status = getFileInfo(path);
+ if (file_status) {
+ $('.file_manager').trigger('enter-key');
+ }
+ }
+ }
+ }
+ };
+
+ self.data_cap = cap;
+
+ $('.storage_dialog #uploader .input-path').keyup(function(e) {
+ if(e.keyCode == 13) {
+ e.stopPropagation();
+ var path = $(this).val();
+ if(config.options.platform_type != "win32" && path.startsWith('/') == false) {
+ path = '/' + path;
+ $(this).val(path);
+ }
+ setTimeout(function() {
+ check_obj(path, true);
+ });
+
+ return;
+ }
+ check_obj($(this).val(), false);
+ });
+ }
+ this.set_cap = function(cap) {
+ this.data_cap = cap;
+ }
+}
+
+var input_object = new InputObject()
+input_object.init(data);
+
// Upload file
if (has_capability(data, 'upload')) {
Dropzone.autoDiscover = false;
@@ -1495,7 +1568,7 @@ if (has_capability(data, 'upload')) {
var data = response.data.result,
$this = $(file.previewTemplate);
- if (data.Code == 0) {
+ if (data.Code == 1) {
setTimeout(function() {
$this.find(".dz-upload").addClass("success");
}, 1000);
diff --git a/web/pgadmin/tools/sqleditor/__init__.py b/web/pgadmin/tools/sqleditor/__init__.py
index 4e1efd5..ec10459 100644
--- a/web/pgadmin/tools/sqleditor/__init__.py
+++ b/web/pgadmin/tools/sqleditor/__init__.py
@@ -8,8 +8,6 @@
##########################################################################
"""A blueprint module implementing the sqleditor frame."""
-MODULE_NAME = 'sqleditor'
-
import simplejson as json
import os
import pickle
@@ -26,7 +24,9 @@ from pgadmin.utils.ajax import make_json_response, bad_request, \
from pgadmin.utils.driver import get_driver
from pgadmin.utils.sqlautocomplete.autocomplete import SQLAutoComplete
-from config import PG_DEFAULT_DRIVER
+from config import PG_DEFAULT_DRIVER, SERVER_MODE
+
+MODULE_NAME = 'sqleditor'
# import unquote from urlib for python2.x and python3.x
try:
@@ -1267,6 +1267,17 @@ def save_file():
storage_manager_path,
unquote(file_data['file_name'].lstrip('/'))
)
+
+ try:
+ # Do not allow user to access outside his storage dir in server mode.
+ if SERVER_MODE is True:
+ orig_path = os.path.abspath(file_path)
+ if not orig_path.startswith(storage_manager_path):
+ raise Exception(
+ gettext("Access denied ({})".format(orig_path)))
+ except Exception as e:
+ return internal_server_error(errormsg=str(e))
+
file_content = file_data['file_content']
# write to file
--
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers