Skip to content

Commit 9ec0a91

Browse files
authored
tornado backend error correction
[FileManager class improvements] 1. Copied used to have Move functionality. Method renamed 2. Added correct Copy method 3. Added downloadMultiple method 4. Fixed compress method (security fix)
1 parent efd049f commit 9ec0a91

File tree

1 file changed

+66
-13
lines changed

1 file changed

+66
-13
lines changed

bridges/python/tornado/filemanager.py

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import json
2929
import os
3030
import shutil
31+
import uuid
3132
import stat
3233
import zipfile
3334
import tornado.web
@@ -116,21 +117,35 @@ def rename(self, request):
116117
def copy(self, request):
117118
try:
118119
items = request['items']
120+
path = os.path.abspath(self.root + request['newPath'])
119121
if len(items) == 1 and 'singleFilename' in request:
120122
src = os.path.abspath(self.root + items[0])
121-
dst = os.path.abspath(self.root + request['singleFilename'])
122-
if not (os.path.exists(src) and src.startswith(self.root) and dst.startswith(self.root)):
123+
if not (os.path.exists(src) and src.startswith(self.root) and path.startswith(self.root)):
123124
return {'result': {'success': 'false', 'error': 'File not found'}}
124125

125-
shutil.move(src, dst)
126+
shutil.copy(src, path)
126127
else:
127-
path = os.path.abspath(self.root + request['newPath'])
128128
for item in items:
129129
src = os.path.abspath(self.root + item)
130130
if not (os.path.exists(src) and src.startswith(self.root) and path.startswith(self.root)):
131131
return {'result': {'success': 'false', 'error': 'Invalid path'}}
132132

133-
shutil.move(src, path)
133+
shutil.copy(src, path)
134+
except Exception as e:
135+
return {'result': {'success': 'false', 'error': e.message}}
136+
137+
return {'result': {'success': 'true', 'error': ''}}
138+
139+
def move(self, request):
140+
try:
141+
items = request['items']
142+
path = os.path.abspath(self.root + request['newPath'])
143+
for item in items:
144+
src = os.path.abspath(self.root + item)
145+
if not (os.path.exists(src) and src.startswith(self.root) and path.startswith(self.root)):
146+
return {'result': {'success': 'false', 'error': 'Invalid path'}}
147+
148+
shutil.move(src, path)
134149
except Exception as e:
135150
return {'result': {'success': 'false', 'error': e.message}}
136151

@@ -226,14 +241,15 @@ def compress(self, request):
226241
continue
227242

228243
if os.path.isfile(path):
229-
zip_file.write(path)
244+
zip_file.write(path, item)
230245
else:
246+
zip_file.write(path, arcname=os.path.basename(path))
247+
231248
for root, dirs, files in os.walk(path):
232-
for f in files:
233-
zip_file.write(
234-
f,
235-
os.path.relpath(os.path.join(root, f), os.path.join(path, '..'))
236-
)
249+
if root != path:
250+
zip_file.write(root, arcname=os.path.relpath(root, os.path.dirname(path)))
251+
for filename in files:
252+
zip_file.write(os.path.join(root, filename), arcname=os.path.join(os.path.relpath(root, os.path.dirname(path)), filename))
237253

238254
zip_file.close()
239255
except Exception as e:
@@ -274,28 +290,65 @@ def upload(self, handler):
274290

275291
def download(self, path):
276292
path = os.path.abspath(self.root + path)
277-
print(path)
278293
content = ''
279294
if path.startswith(self.root) and os.path.isfile(path):
280-
print(path)
281295
try:
282296
with open(path, 'rb') as f:
283297
content = f.read()
284298
except Exception as e:
285299
pass
286300
return content
287301

302+
def downloadMultiple(self, items, filename):
303+
temp_zip_filename = str(uuid.uuid4())
304+
zipfile_path = os.path.abspath(os.path.join(self.root, temp_zip_filename))
305+
zip_file = zipfile.ZipFile(zipfile_path, 'w', zipfile.ZIP_DEFLATED)
306+
for item in items:
307+
path = os.path.abspath(self.root + item)
308+
if not (os.path.exists(path) and path.startswith(self.root)):
309+
continue
310+
311+
if os.path.isfile(path):
312+
zip_file.write(path, item)
313+
else:
314+
pass
315+
zip_file.close()
316+
317+
content = ''
318+
f = open(zipfile_path,'rb')
319+
content = f.read()
320+
f.close()
321+
os.remove(zipfile_path)
322+
return content
323+
288324

289325
class FileManagerHandler(tornado.web.RequestHandler):
290326
def initialize(self, root='/', show_dotfiles=True):
291327
self.filemanager = FileManager(root, show_dotfiles)
292328

293329
def get(self):
330+
294331
action = self.get_query_argument('action', '')
295332
path = self.get_query_argument('path', '')
333+
items = self.get_query_arguments('items')
334+
toFilename = self.get_query_argument('toFilename', '')
335+
296336
if action == 'download' and path:
297337
result = self.filemanager.download(path)
298338
self.write(result)
339+
340+
file_name = os.path.basename(path)
341+
self.set_header('Content-Type', 'application/force-download')
342+
self.set_header('Content-Disposition', 'attachment; filename=%s' % file_name)
343+
elif action == 'downloadMultiple' and len(items) > 0 and toFilename:
344+
result = self.filemanager.downloadMultiple(items,toFilename)
345+
self.write(result)
346+
347+
file_name = os.path.basename(toFilename)
348+
self.set_header('Content-Type', 'application/force-download')
349+
self.set_header('Content-Disposition', 'attachment; filename=%s' % file_name)
350+
else:
351+
pass
299352

300353
def post(self):
301354
if self.request.headers.get('Content-Type').find('multipart/form-data') >= 0:

0 commit comments

Comments
 (0)