Skip to content

Commit d686591

Browse files
committed
Handle kindly system permissions
1 parent 3d41ba7 commit d686591

38 files changed

+202
-111
lines changed

Diff for: ReadMe.md

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Main features
2323
* Several computer language connectors available. **PHP is up-to-date**
2424
* Ability to upload, delete, modify, download and move files
2525
* Ability to create folders
26+
* Support user permissions - based on session
27+
* Handle system permissions
2628
* Multiple uploads support - based on [dropzonejs](http://www.dropzonejs.com)
2729
* Online text / code edition - based on [codeMirror](http://codemirror.net/)
2830
* [Opening a given folder](https://github.com/simogeo/Filemanager/wiki/How-to-open-a-given-folder-different-from-root-folder-when-opening-the-filemanager%3F)
@@ -186,6 +188,7 @@ Example Response:
186188
"Filename": "logo.png",
187189
"File Type": "png",
188190
"Preview": "/UserFiles/Image/logo.png",
191+
"Protected": 0,
189192
"Properties": {
190193
"Date Created": null,
191194
"Date Modified": "02/09/2007 14:01:06",
@@ -211,6 +214,8 @@ The keys are as follows:
211214
Directories: images/fileicons/_Open.png
212215
Files: images/fileicons/[extension].png
213216
Unknown: images/fileicons/default.png
217+
218+
Protected: Indicates if the file has some reading / writing restrictions. If not, set to 0. Else set to 1.
214219

215220
Properties: A nested JSON object containing specific properties of the file.
216221

@@ -244,6 +249,7 @@ Example Response:
244249
"Filename": "logo.png",
245250
"File Type": "png",
246251
"Preview": "/UserFiles/Image/logo.png",
252+
"Protected": 0,
247253
"Properties": {
248254
"Date Created": null,
249255
"Date Modified": "02/09/2007 14:01:06",

Diff for: connectors/php/filemanager.class.php

+71-29
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,11 @@ public function getinfo() {
195195
$path = $this->get['path'];
196196
}
197197

198-
199198
$array = array(
200199
'Path'=> $path,
201200
'Filename'=>$this->item['filename'],
202201
'File Type'=>$this->item['filetype'],
202+
'Protected'=>$this->item['protected'],
203203
'Preview'=>$this->item['preview'],
204204
'Properties'=>$this->item['properties'],
205205
'Error'=>"",
@@ -222,6 +222,12 @@ public function getfolder() {
222222
if(!is_dir($current_path)) {
223223
$this->error(sprintf($this->lang('DIRECTORY_NOT_EXIST'),$this->get['path']));
224224
}
225+
226+
// check if file is readable
227+
if(!$this->has_system_permission($current_path, array('r'))) {
228+
$this->error(sprintf($this->lang('NOT_ALLOWED_SYSTEM')));
229+
}
230+
225231
if(!$handle = @opendir($current_path)) {
226232
$this->error(sprintf($this->lang('UNABLE_TO_OPEN_DIRECTORY'),$this->get['path']));
227233
} else {
@@ -240,11 +246,22 @@ public function getfolder() {
240246

241247
if(is_dir($current_path . $file)) {
242248
if(!in_array($file, $this->config['exclude']['unallowed_dirs']) && !preg_match( $this->config['exclude']['unallowed_dirs_REGEXP'], $file)) {
249+
250+
// check if file is writable and readable
251+
if(!$this->has_system_permission($current_path . $file, array('w', 'r'))) {
252+
$protected = 1;
253+
$previewPath = $this->config['icons']['path'] . 'locked_' . $this->config['icons']['directory'];
254+
} else {
255+
$protected =0;
256+
$previewPath = $this->config['icons']['path'] . $this->config['icons']['directory'];
257+
}
258+
243259
$array[$this->get['path'] . $file .'/'] = array(
244260
'Path'=> $this->get['path'] . $file .'/',
245261
'Filename'=>$file,
246262
'File Type'=>'dir',
247-
'Preview'=> $this->config['icons']['path'] . $this->config['icons']['directory'],
263+
'Protected'=>$protected,
264+
'Preview'=> $previewPath,
248265
'Properties'=>array(
249266
'Date Created'=> date($this->config['options']['dateFormat'], filectime($this->getFullPath($this->get['path'] . $file .'/'))),
250267
'Date Modified'=> date($this->config['options']['dateFormat'], filemtime($this->getFullPath($this->get['path'] . $file .'/'))),
@@ -261,13 +278,15 @@ public function getfolder() {
261278
$this->item = array();
262279
$this->item['properties'] = $this->properties;
263280
$this->get_file_info($this->get['path'] . $file, true);
281+
264282

265283
if(!isset($this->params['type']) || (isset($this->params['type']) && strtolower($this->params['type'])=='images' && in_array(strtolower($this->item['filetype']),array_map('strtolower', $this->config['images']['imagesExt'])))) {
266284
if($this->config['upload']['imagesOnly']== false || ($this->config['upload']['imagesOnly']== true && in_array(strtolower($this->item['filetype']),array_map('strtolower', $this->config['images']['imagesExt'])))) {
267285
$array[$this->get['path'] . $file] = array(
268286
'Path'=>$this->get['path'] . $file,
269287
'Filename'=>$this->item['filename'],
270288
'File Type'=>$this->item['filetype'],
289+
'Protected'=>$this->item['protected'],
271290
'Preview'=>$this->item['preview'],
272291
'Properties'=>$this->item['properties'],
273292
'Error'=>"",
@@ -289,9 +308,9 @@ public function editfile() {
289308

290309
$current_path = $this->getFullPath();
291310

292-
// check if writable
293-
if(!is_writable($this->getFullPath($current_path))) {
294-
$this->error(sprintf($this->lang('NOT_ALLOWED')));
311+
// check if file is writable
312+
if(!$this->has_system_permission($current_path, array('w'))) {
313+
$this->error(sprintf($this->lang('NOT_ALLOWED_SYSTEM')));
295314
}
296315

297316
if(!$this->has_permission('edit') || !$this->is_valid_path($current_path) || !$this->is_editable($current_path)) {
@@ -325,7 +344,7 @@ public function savefile() {
325344
$this->error("No way.");
326345
}
327346

328-
if(!is_writable($current_path)) {
347+
if(!$this->has_system_permission($current_path, array('w'))) {
329348
$this->error(sprintf($this->lang('ERROR_WRITING_PERM')));
330349
}
331350

@@ -366,9 +385,9 @@ public function rename() {
366385
$this->error("No way.");
367386
}
368387

369-
// check if writable
370-
if(!is_writable($this->getFullPath($old_file))) {
371-
$this->error(sprintf($this->lang('NOT_ALLOWED')));
388+
// check if file is writable
389+
if(!$this->has_system_permission($old_file, array('w'))) {
390+
$this->error(sprintf($this->lang('NOT_ALLOWED_SYSTEM')),true);
372391
}
373392

374393
// check if not requesting main FM userfiles folder
@@ -423,11 +442,12 @@ public function move() {
423442
$rootDir = str_replace('//', '/', $rootDir);
424443
$oldPath = $this->getFullPath($this->get['old']);
425444

426-
// check if writable
427-
if(!is_writable($this->getFullPath($oldPath))) {
428-
$this->error(sprintf($this->lang('NOT_ALLOWED')));
445+
// check if file is writable
446+
if(!$this->has_system_permission($oldPath, array('w'))) {
447+
$this->error(sprintf($this->lang('NOT_ALLOWED_SYSTEM')),true);
429448
}
430449

450+
431451
// check if not requesting main FM userfiles folder
432452
if($this->is_root_folder($oldPath)) {
433453
$this->error(sprintf($this->lang('NOT_ALLOWED')),true);
@@ -499,15 +519,16 @@ public function delete() {
499519
$current_path = $this->getFullPath();
500520
$thumbnail_path = $this->get_thumbnail_path($current_path);
501521

502-
// check if writable
503-
if(!is_writable($this->getFullPath($current_path))) {
504-
$this->error(sprintf($this->lang('NOT_ALLOWED')));
505-
}
506522

507523
if(!$this->has_permission('delete') || !$this->is_valid_path($current_path)) {
508524
$this->error("No way.");
509525
}
510526

527+
// check if file is writable
528+
if(!$this->has_system_permission($current_path, array('w'))) {
529+
$this->error(sprintf($this->lang('NOT_ALLOWED_SYSTEM')));
530+
}
531+
511532
// check if not requesting main FM userfiles folder
512533
if($this->is_root_folder($current_path)) {
513534
$this->error(sprintf($this->lang('NOT_ALLOWED')));
@@ -603,9 +624,9 @@ public function replace() {
603624

604625
$current_path = $this->getFullPath($this->post['newfilepath']);
605626

606-
// check if writable
607-
if(!is_writable($this->getFullPath($current_path))) {
608-
$this->error(sprintf($this->lang('NOT_ALLOWED')), true);
627+
// check if file is writable
628+
if(!$this->has_system_permission($current_path, array('w'))) {
629+
$this->error(sprintf($this->lang('NOT_ALLOWED_SYSTEM')), true);
609630
}
610631

611632
if(!$this->has_permission('replace') || !$this->is_valid_path($current_path)) {
@@ -818,15 +839,15 @@ public function download() {
818839

819840
$current_path = $this->getFullPath();
820841

821-
// check if writable
822-
if(!is_writable($this->getFullPath($current_path))) {
823-
$this->error(sprintf($this->lang('NOT_ALLOWED')));
824-
}
825-
826842
if(!$this->has_permission('download') || !$this->is_valid_path($current_path)) {
827843
$this->error("No way.");
828844
}
829845

846+
// check if file is writable
847+
if(!$this->has_system_permission($current_path, array('w'))) {
848+
$this->error(sprintf($this->lang('NOT_ALLOWED_SYSTEM')),true);
849+
}
850+
830851
// we check if extension is allowed regarding the security Policy settings
831852
if(is_file($current_path)) {
832853
if(!$this->is_allowed_file_type(basename($current_path))) {
@@ -936,6 +957,20 @@ private function setPermissions() {
936957
if($this->config['edit']['enabled']) array_push($this->allowed_actions, 'edit');
937958

938959
}
960+
961+
// check if system permission is granted
962+
private function has_system_permission($filepath, $perms) {
963+
964+
if(in_array('r', $perms)) {
965+
if(!is_readable($filepath)) return false;
966+
}
967+
if(in_array('w', $perms)) {
968+
if(!is_writable($filepath)) return false;
969+
}
970+
971+
return true;
972+
973+
}
939974

940975

941976
private function get_file_info($path='', $thumbnail = false) {
@@ -954,12 +989,19 @@ private function get_file_info($path='', $thumbnail = false) {
954989
$this->item['filetype'] = $tmp[(sizeof($tmp)-1)];
955990
$this->item['filemtime'] = filemtime($this->getFullPath($current_path));
956991
$this->item['filectime'] = filectime($this->getFullPath($current_path));
957-
958-
$this->item['preview'] = $this->config['icons']['path'] . $this->config['icons']['default'];
959992

960-
// prevent Internal Server Error HTTP_CODE 500 on non readable files/folders
961-
// without returning errors
962-
if(!is_readable($this->getFullPath($current_path))) return;
993+
// check if file is writable and readable
994+
if(!$this->has_system_permission($this->getFullPath($current_path), array('w', 'r'))) {
995+
$this->item['protected'] = 1;
996+
$this->item['preview'] = $this->config['icons']['path'] . 'locked_' . $this->config['icons']['default'];
997+
// prevent Internal Server Error HTTP_CODE 500 on non readable files/folders
998+
// without returning errors
999+
return;
1000+
1001+
} else {
1002+
$this->item['protected'] = 0;
1003+
$this->item['preview'] = $this->config['icons']['path'] . $this->config['icons']['default'];
1004+
}
9631005

9641006
if(is_dir($current_path)) {
9651007

Diff for: images/fileicons/locked__Open.png

6.46 KB
Loading

Diff for: images/fileicons/locked_default.png

5.67 KB
Loading

Diff for: images/fileicons/zip.png

1.41 KB
Loading

Diff for: scripts/filemanager.js

+15-16
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ var getFileInfo = function(file) {
12521252
getAudioPlayer(data);
12531253
}
12541254

1255-
if(isEditableFile(data['Filename']) && config.edit.enabled == true) {
1255+
if(isEditableFile(data['Filename']) && config.edit.enabled == true && data['Protected']==0) {
12561256
editItem(data);
12571257
}
12581258

@@ -1264,13 +1264,16 @@ var getFileInfo = function(file) {
12641264
} else {
12651265
var url = window.location.protocol + '//' + window.location.host + data['Path'];
12661266
}
1267-
$('#fileinfo').find('div#tools').append(' <a id="copy-button" data-clipboard-text="'+ url + '" title="' + lg.copy_to_clipboard + '" href="#"><span>' + lg.copy_to_clipboard + '</span></a>');
1268-
// loading zeroClipboard code
1269-
loadJS('./scripts/zeroclipboard/copy.js?d' + d.getMilliseconds());
1270-
$('#copy-button').click(function () {
1271-
$('#fileinfo').find('div#tools').append('<span id="copied">' + lg.copied + '</span>');
1272-
$('#copied').delay(500).fadeOut(1000, function() { $(this).remove(); });
1273-
});
1267+
if(data['Protected']==0) {
1268+
$('#fileinfo').find('div#tools').append(' <a id="copy-button" data-clipboard-text="'+ url + '" title="' + lg.copy_to_clipboard + '" href="#"><span>' + lg.copy_to_clipboard + '</span></a>');
1269+
// loading zeroClipboard code
1270+
1271+
loadJS('./scripts/zeroclipboard/copy.js?d' + d.getMilliseconds());
1272+
$('#copy-button').click(function () {
1273+
$('#fileinfo').find('div#tools').append('<span id="copied">' + lg.copied + '</span>');
1274+
$('#copied').delay(500).fadeOut(1000, function() { $(this).remove(); });
1275+
});
1276+
}
12741277

12751278
var properties = '';
12761279

@@ -1490,10 +1493,12 @@ var populateFileTree = function(path, callback) {
14901493
}
14911494
}
14921495
if (data[key]['File Type'] == 'dir') {
1493-
result += "<li class=\"directory collapsed\"><a href=\"#\" class=\"" + cap_classes + "\" data-path=\"" + data[key]['Path'] + "\">" + data[key]['Filename'] + "</a></li>";
1496+
var extraclass = data[key]['Protected'] == 0 ? '' : ' directory-locked';
1497+
result += "<li class=\"directory collapsed" + extraclass + "\"><a href=\"#\" class=\"" + cap_classes + "\" data-path=\"" + data[key]['Path'] + "\">" + data[key]['Filename'] + "</a></li>";
14941498
} else {
14951499
if(config.options.listFiles) {
1496-
result += "<li class=\"file ext_" + data[key]['File Type'].toLowerCase() + "\"><a href=\"#\" class=\"" + cap_classes + "\" data-path=\"" + data[key]['Path'] + "\">" + data[key]['Filename'] + "</a></li>";
1500+
var extraclass = data[key]['Protected'] == 0 ? '' : ' file-locked';
1501+
result += "<li class=\"file ext_" + data[key]['File Type'].toLowerCase() + extraclass + "\"><a href=\"#\" class=\"" + cap_classes + "\" data-path=\"" + data[key]['Path'] + "\">" + data[key]['Filename'] + "</a></li>";
14971502
}
14981503
}
14991504
}
@@ -1847,12 +1852,6 @@ $(function(){
18471852
});
18481853
}
18491854

1850-
// Creates file tree.
1851-
// setTimeout() necessary to fix bugs
1852-
// see https://github.com/malihu/malihu-custom-scrollbar-plugin/issues/237
1853-
// and https://github.com/simogeo/Filemanager/issues/302
1854-
// setTimeout(function(){ createFileTree(); }, 400);
1855-
// createFileTree();
18561855
// Loading CustomScrollbar if enabled
18571856
// Important, the script should be called after calling createFileTree() to prevent bug
18581857
if(config.customScrollbar.enabled) {

0 commit comments

Comments
 (0)