Studio-42 / elFinder

📁 Open-source file manager for web, written in JavaScript using jQuery and jQuery UI
https://studio-42.github.io/elFinder/
Other
4.65k stars 1.42k forks source link

Root volume access control #1457

Closed paulcanning closed 8 years ago

paulcanning commented 8 years ago

Is there a simple way to change access control for the root volume?

I want users to be able to upload into subfolders, but not into the root volume itself.

Can this simply be done with the attributes? If so, what does the pattern need to be to match the root volume?

o1eksiy commented 8 years ago

If you use laravel you be able to change the plugin configuration via "middleware" See https://github.com/barryvdh/laravel-elfinder/issues/62

ghost commented 8 years ago

You could modify the connector so it gets the current logged in user, and creates the credentials on the fly so they only have access to their designated folder. For e.g. when creating a user account you could have a folder created using their username, then when elFinder is initialised, if your using cookie's or a session id for logged in users, the connector can grab that, then use that data to set the folder they have access to.

paulcanning commented 8 years ago

Guys, I just want to be able to stop uploads to the root volume.

Like using the disabled option, but only for the root volume, not every folder/file in it (which is what that option does, I tried it)

paulcanning commented 8 years ago

@StudioJunkyard I am basically doing that, but I am talking about the root volume itself.

ghost commented 8 years ago

Are users able to change to the root folder, even if you specifally set their user folder?

$opts=array(
    'roots'=>array(
        array(
            'path'=>$_SERVER["DOCUMENT_ROOT"].DS.$settings['system']['url'].DS.'media'.DS,
            'URL'=>URL.'media/',
        )
    )
)

Is this the options your using to set their user folder, it's what I would do, but add their folder, after the media? From my understanding, doing that would make it so that would be that user's root folder.

paulcanning commented 8 years ago

Users have access to lots of sub-folders, so ideally I don't want to be adding a root volume for each of the sub-folders :/

nao-pon commented 8 years ago

@paulcanning What about volume root option accessControl?

Note: Use \ instead of / on the windows server.

function function access($attr, $path) {
    if (rtrim($path, '/') === '/ABSOLUTE_PATH_TO/elfinder_root/files') {
        return ($attr == 'read' || $attr == 'locked');   // set read+locked to true, other (write+hidden) set to false
    }
    // And more rules here
    // e.g. basic control of file/folder begins with '.' (dot).`
    return strpos(basename($path), '.') === 0       // if file/folder begins with '.' (dot)
        ? !($attr == 'read' || $attr == 'write')    // set read+write to false, other (locked+hidden) set to true
        :  null;                                    // else elFinder decide it itself

}

in root opts

'accessControl' => 'access'
paulcanning commented 8 years ago

I tried this code, and when loading the page afresh, all folders and files under the root, are passed though the access control function, EXCEPT for the root itself! So this code it useless to me.

e.g

nao-pon commented 8 years ago

I want users to be able to upload into subfolders, but not into the root volume itself.

The previous code just works that way. Currently the my test site in this state.

paulcanning commented 8 years ago

I don't see how, as I said, I tried it, and the root path was never passed through the function!

nao-pon commented 8 years ago

The state of my test site is not what you want?

paulcanning commented 8 years ago

Yes, it is. But I do not understand how you have stopped uploads to the root, using the code above, when the code above does not pass the root volume path to it at any point!

nao-pon commented 8 years ago

Function specified in accessControl is called each time the authority decision of all of the items.

paulcanning commented 8 years ago

I don't think you are understanding me.

You stated that accessControl can be used to set the read, write, locked and hidden options for the ROOT volume (the root folder that contains everything else. The same as Test Here on your test site)

However, when I used the code you posted above, and I run the connector with a break point on the access method, the path of the ROOT volume is NEVER passed to the method, meaning it can NEVER be checked and its read, write, locked and hidden options can NEVER be set.

I then asked how you achieved this on your test site, and you have simply failed to provide a clear answer and then just closed this issue.

ghost commented 8 years ago

I tried it myself on my local machine, using what @nao-pon described, using Linux Mint, Apache, and it worked as @nao-pon described. Check you haven't made a typo, or it's possible some other system settings is stopping things working as expected.

ghost commented 8 years ago

You could also use .htaccess to stop files being uploaded to folders, essentially blocking selected folders.

paulcanning commented 8 years ago

@StudioJunkyard I tested it several times, and that method simply did not work for checking the root path. If I could take a screen capture, I would.

The method is passed all the various sub-folders etc, but never the root volume path.

ghost commented 8 years ago

Are you still doing this on a Windows Box? I wonder, if like the 2GB limit issue you had on another issue, might also be something to do with this as well.

paulcanning commented 8 years ago

@StudioJunkyard sorry but what are you talking about? Why would Windows stop one file path form being shown, when ALL OTHER files and folders (directly under the ROOT) be passed to the accessControl method, and block the ROOT path from being passed through?

Hint, IT WON'T

ghost commented 8 years ago

Well, it seems like your the expert. I'm not having the issue's your having, so I must not know what I'm doing, go figure.

Was just making suggestions, that you may not have thought of.

PHP, can and will behave differently in a Windows Environment. The majority of servers run some derivative of Linux these days, hence why most developer's use Linux, even Locally for testing.

paulcanning commented 8 years ago

I understand PHP can behave differently under different OS environments, but what you mentioned simply is not the case. Just think about it. Why would Windows block the path of the root volume going through to a method?

Both you and @nao-pon have yet to actually show the exact code you are using.

Please provide your full connector script.

ghost commented 8 years ago

@nao-pon has, scroll up, I tried what he suggested and it worked. There MUST be something your missing, or it's something to do with using Windows.

I don't see how sharing my connector script is going to help you, anyway, let's see if you understand how I've modified mine:

<?php
error_reporting(0);
define('DS',DIRECTORY_SEPARATOR);
include_once dirname(__FILE__).DS.'elFinderConnector.class.php';
include_once dirname(__FILE__).DS.'elFinder.class.php';
include_once dirname(__FILE__).DS.'elFinderVolumeDriver.class.php';
include_once dirname(__FILE__).DS.'elFinderVolumeLocalFileSystem.class.php';
$settings=parse_ini_file('..'.DS.'..'.DS.'..'.DS.'core'.DS.'config.ini',TRUE);
if((!empty($_SERVER['HTTPS'])&&$_SERVER['HTTPS']!=='off')||$_SERVER['SERVER_PORT']==443)
    define('PROTOCOL','https://');
else
    define('PROTOCOL','http://');
define('URL',PROTOCOL.$_SERVER['HTTP_HOST'].$settings['system']['url'].'/');
function access($attr,$path,$data,$volume){
    return strpos(basename($path),'.')===0?!($attr=='read'||$attr=='write'):null;
}
$opts=array(
    'roots'=>array(
        array(
            'imgLib'=>'gd',
            'driver'=>'LocalFileSystem',
            'path'=>$_SERVER["DOCUMENT_ROOT"].DS.$settings['system']['url'].DS.'media'.DS,
            'URL'=>URL.'media/',
            'uploadDeny'=>array(
                'all'
            ),
            'uploadAllow'=>array(
                'image',
                'text/plain'
            ),
            'uploadOrder'=>array(
                'deny',
                'allow'
            ),
            'accessControl'=>'access',
            'attributes'=>array(
                array(
                    'pattern'=>'',
//                    'pattern'=>'!^/orders|backup|avatar!',
                    'hidden'=>true
                )
            )
        )
    )
);
$connector=new elFinderConnector(new elFinder($opts));
$connector->run();
paulcanning commented 8 years ago

And your access method?

Also, put a breakpoint on your access method and load your elFinder. Check the $path parameter and see if it starts with the root volume (in your case, media) or if it starts with the first sub-directory under media

EDIT - sorry, didn't see your method there hidden away.

ghost commented 8 years ago

I've already mentioned, I tried what @nao-pon described and it worked. As I keep saying, it has to be something your doing, or some quirk with Windows. I remember having weird directory structure issue's even back in the XP days with folder recursion, and other weird permissions issue's with access. All those issue's went away after switching to Linux. I don't remember what I'd done to resolve things back then, and it could be different to what your getting now, as elFinder wasn't around back then.

ghost commented 8 years ago

Have you tried this in Linux at all, just to compare if it is a Windows thing?

paulcanning commented 8 years ago

Please, do the break point thing and show me the first read out of the variables captured by the access method. I want to see what you get when it supposedly shows the root volume parameters

paulcanning commented 8 years ago

I am using Google Cloud Storage by the way, as my main volume.

However, I tried with a Local File system, and it's still not working. When I load the root volume, the first path that is fed through is for the .quarantine folder.

ghost commented 8 years ago

Give me exactly what you want me to try for the access. And I'll see if what your using works?

paulcanning commented 8 years ago

Just use yours. Put a break point on the IF statement and load the page. Then check the method variables. According to you and @nao-pon , the first $path variable (seeing as it is the root volume) should be, for you, something like /media/, with $attr being read

Oh, and please remove all the uploadDeny and uploadAllow settings. I am not using those, as @nao-pon stated I could just use the accessControl option, and, if it works how it is supposed to, setting the write option to false for the root volume should stop uploads to it.

ghost commented 8 years ago

There should also be a .tmb folder created. The only thing the IF statement does is determine if the protocol of the site uses https or http, then that info is used to parse the file path back to the calling method to give the files full path. It doesn't affect how folder, or files are accessed in elFinder. This isn't going to affect the access of anything.

Do you mean to modify the Ternary Operator in the access function, if so, say what you mean.

The path option is what elFinder uses to work with files.

paulcanning commented 8 years ago

The IF statement in your access method. I didn't read your code fully and assumed you used the exact code as @nao-pon posted. I've not had my morning coffee yet.

$path actually picks up directories as well, at least, for me it does. Just no the root one..

ghost commented 8 years ago

$path is what elF uses to work with files.

That IF is a Ternary operator, like an IF but not an IF, basically a shorthanded IF.

Anyway, I tried it again just now, it shows the root folder, and the other folders within it, but won't allow uploads to the root folder "/media", but will allows uploads into the folders within it.

paulcanning commented 8 years ago

I know what a ternary is, I just didn't see it in your code, I thought you were using the code @nao-pon posted, which has a long-hand IF statement, to check the $path variable.

Can you post a screenshot of your break point info?

Also, what version of elFinder are you using?

My access method simply won't work the same as yours.

paulcanning commented 8 years ago

I am still having this issue.

As explained previously, using your exact code, the root volume path is never passed through to the accessControl function, hence it cannot be locked (to stop uploads).

nao-pon commented 8 years ago

@paulcanning Please show us your accessControl function.

paulcanning commented 8 years ago
public function accessControl($attr, $path, $data, $volume)
    {
        if (rtrim($path, "\\") === "\\")
        {
            return ($attr == 'write' || $attr == 'locked');
        }
    }

I have tried over and over, and no matter what, when I click on a root volume (a google cloud bucket) it is 100000% NOT passed to the access control method. All files and sub folders are passed, but not the root volume.