I have a url that is

filemgr.php

when a user navigates to lower levels of said file manager it shows up as

filemgr.php#userfiles/username/Images

Is there a way to just have it show up as

filemgr.php

with out the rest of the url showing?

I am open to .htaccess editing and php code.

So something like this would work?

# Nice looking URLs (no query string)
# domain.com/category-name-1/ to domain.com/category.php?name=category-name-1
RewriteRule   ^([A-Za-z0-9-]+)/?$   filemgr.php [L]
Member Avatar

diafol

Have you tried it?

No, it still shows up when i go into a subfolder...

Diafol, I think it would be easier to set a condition to check if that user is logged in, but I am finding it difficult to set that condition, here is my PHP code to get the file list and such based on username, where and what would i set to test if said user is trying to access a different users folder?

setlocale(LC_ALL,'en_US.UTF-8');

$tmp = realpath($_REQUEST['file']);
if($tmp === false)
err(404,'File or Directory Not Found');
if(substr($tmp, 0,strlen(__DIR__)) !== __DIR__)
err(403,"Forbidden");

if(!$_COOKIE['_sfm_xsrf'])
setcookie('_sfm_xsrf',bin2hex(openssl_random_pseudo_bytes(16)));
if($_POST) {
if($_COOKIE['_sfm_xsrf'] !== $_POST['xsrf'] || !$_POST['xsrf'])
err(403,"XSRF Failure");
}
$file = $_REQUEST['file'] ?: './userfiles/'.htmlentities($_SESSION['username']);

if($_GET['do'] == 'list') {
if (is_dir($file)) {
$directory = $file;
$result = array();
$files = array_diff(scandir($directory), array('.','..'));
foreach($files as $entry) if($entry !== basename(__FILE__)) {
     $i = $directory . '/' . $entry;
$stat = stat($i);
$result[] = array(
'mtime' => $stat['mtime'],
'size' => $stat['size'],
'name' => basename($i),
'path' => preg_replace('@^\./@', '', $i),
'is_dir' => is_dir($i),
'is_deleteable' => (!is_dir($i) && is_writable($directory)) ||
(is_dir($i) && is_writable($directory) && is_recursively_deleteable($i)),
'is_readable' => is_readable($i),
'is_writable' => is_writable($i),
'is_executable' => is_executable($i),
);
}
} else {
err(412,"Not a Directory");
}
echo json_encode(array('success' => true, 'is_writable' => is_writable($file), 'results' =>$result));
exit;
} elseif ($_POST['do'] == 'delete') {
rmrf($file);
exit;
} elseif ($_POST['do'] == 'mkdir') {
chdir($file);
@mkdir($_POST['name']);
exit;
} elseif ($_POST['do'] == 'upload') {
var_dump($_POST);
var_dump($_FILES);
var_dump($_FILES['file_data']['tmp_name']);
var_dump(move_uploaded_file($_FILES['file_data']['tmp_name'], $file.'/'.$_FILES['file_data']['name']));
exit;
} elseif ($_GET['do'] == 'download') {
$filename = basename($file);
header('Content-Type: ' . mime_content_type($file));
header('Content-Length: '. filesize($file));
header(sprintf('Content-Disposition: attachment; filename=%s',
strpos('MSIE',$_SERVER['HTTP_REFERER']) ? rawurlencode($filename) : "\"$filename\"" ));
ob_flush();
readfile($file);
exit;
}
function rmrf($dir) {
if(is_dir($dir)) {
$files = array_diff(scandir($dir), array('.','..'));
foreach ($files as $file)
rmrf("$dir/$file");
rmdir($dir);
} else {
unlink($dir);
}
}
function is_recursively_deleteable($d) {
$stack = array($d);
while($dir = array_pop($stack)) {
if(!is_readable($dir) || !is_writable($dir))
return false;
$files = array_diff(scandir($dir), array('.','..'));
foreach($files as $file) if(is_dir($file)) {
$stack[] = "$dir/$file";
}
}
return true;
}

function err($code,$msg) {
echo json_encode(array('error' => array('code'=>intval($code), 'msg' => $msg)));
exit;
}

function asBytes($ini_v) {
$ini_v = trim($ini_v);
$s = array('g'=> 1<<30, 'm' => 1<<20, 'k' => 1<<10);
return intval($ini_v) * ($s[strtolower(substr($ini_v,-1))] ?: 1);
}

$MAX_UPLOAD_SIZE = min(asBytes(ini_get('post_max_size')), asBytes(ini_get('upload_max_filesize')));

line 15 is where it sets the directory for the user.

Member Avatar

diafol

Sorry patk, the code isn't indented, so it's too difficult (for me) to read.

This is what i see...

Apache mod_rewrite is not going to help for anchors (the #portion that comes after the URI) because only the web browser / client sees them, not the server.

Dani, yea, i seen that, it gets set by the jquery that I have. I have tried to take it out but then the file manager will not work. I think what i need is to set a php condition that says if user x tries to access user b's files echo Not allowed, but I am unsure where to put the conditions or how to structure it. I have tried:

if($file == $_SESSION['username']){
//continue with code

//php code here

}else{
echo'Not allowed to access these files.';

but that didnt work, I know it has to do with the session variable that is in there. Since the users file manager is set at page load. But if you take the #userfiles/username/subfolder and change the username to usernamex it will show that users files.

Member Avatar

diafol

Ah - sorry I missed the # :(

This is what i see...

Yes same here - like I said it's not indented pther thaan the odd line here and there.

Yea, My Jquery code creates the # using an attr.() function if there is a directory. That is when the #userfiles/username/subfolder appears in the url. I am wanting to stop that or change so they cannont change the username in the url.

This is my jquery code:

function renderFileRow(data) {
var $link = $('<a class="name" />')
    .attr('href', data.is_dir ? '#' + data.path : './'+data.path)
    .text(data.name);
    var $dl_link = $('<a/>').attr('href','?do=download&file='+encodeURIComponent(data.path))
    .addClass('download').text('download');
var $delete_link = $('<a href="#" />').attr('data-file',data.path).addClass('delete').text('delete');
var perms = [];
    if(data.is_readable) perms.push('read');
    if(data.is_writable) perms.push('write');
    if(data.is_executable) perms.push('exec');
var $html = $('<tr />')
    .addClass(data.is_dir ? 'is_dir' : '')
    .append( $('<td class="first" />').append($link) )
    .append( $('<td/>').attr('data-sort',data.is_dir ? -1 : data.size)
    .html($('<span class="size" />').text(formatFileSize(data.size))) )
    .append( $('<td/>').attr('data-sort',data.mtime).text(formatTimestamp(data.mtime)) )
    .append( $('<td/>').text(perms.join('+')) )
    .append( $('<td/>').append($dl_link).append( data.is_deleteable ? $delete_link : '') )
return $html;
}
Member Avatar

diafol

This is what I mean by indenting. There are lots of different formats - this is a quick and dirty reindent using the C++ re-indenter in Notepad++ :

<?php
setlocale(LC_ALL,'en_US.UTF-8');
$tmp = realpath($_REQUEST['file']);
if($tmp === false)
    err(404,'File or Directory Not Found');
if(substr($tmp, 0,strlen(__DIR__)) !== __DIR__)
    err(403,"Forbidden");
if(!$_COOKIE['_sfm_xsrf'])
    setcookie('_sfm_xsrf',bin2hex(openssl_random_pseudo_bytes(16)));
if($_POST) {
    if($_COOKIE['_sfm_xsrf'] !== $_POST['xsrf'] || !$_POST['xsrf'])
        err(403,"XSRF Failure");
}
$file = $_REQUEST['file'] ?: './userfiles/'.htmlentities($_SESSION['username']);
if($_GET['do'] == 'list') {
    if (is_dir($file)) {
        $directory = $file;
        $result = array();
        $files = array_diff(scandir($directory), array('.','..'));
        foreach($files as $entry) if($entry !== basename(__FILE__)) {
            $i = $directory . '/' . $entry;
            $stat = stat($i);
            $result[] = array(
                'mtime' => $stat['mtime'],
                'size' => $stat['size'],
                'name' => basename($i),
                'path' => preg_replace('@^\./@', '', $i),
                'is_dir' => is_dir($i),
                'is_deleteable' => (!is_dir($i) && is_writable($directory)) ||
                    (is_dir($i) && is_writable($directory) && is_recursively_deleteable($i)),
                'is_readable' => is_readable($i),
                'is_writable' => is_writable($i),
                'is_executable' => is_executable($i),
            );
        }
    } else {
        err(412,"Not a Directory");
    }
    echo json_encode(array('success' => true, 'is_writable' => is_writable($file), 'results' =>$result));
    exit;
} elseif ($_POST['do'] == 'delete') {
    rmrf($file);
    exit;
} elseif ($_POST['do'] == 'mkdir') {
    chdir($file);
    @mkdir($_POST['name']);
    exit;
} elseif ($_POST['do'] == 'upload') {
    var_dump($_POST);
    var_dump($_FILES);
    var_dump($_FILES['file_data']['tmp_name']);
    var_dump(move_uploaded_file($_FILES['file_data']['tmp_name'], $file.'/'.$_FILES['file_data']['name']));
    exit;
} elseif ($_GET['do'] == 'download') {
    $filename = basename($file);
    header('Content-Type: ' . mime_content_type($file));
    header('Content-Length: '. filesize($file));
    header(sprintf('Content-Disposition: attachment; filename=%s',
    strpos('MSIE',$_SERVER['HTTP_REFERER']) ? rawurlencode($filename) : "\"$filename\"" ));
    ob_flush();
    readfile($file);
    exit;
}
function rmrf($dir) {
    if(is_dir($dir)) {
        $files = array_diff(scandir($dir), array('.','..'));
        foreach ($files as $file)
        rmrf("$dir/$file");
        rmdir($dir);
    } else {
        unlink($dir);
    }
}
function is_recursively_deleteable($d) {
    $stack = array($d);
    while($dir = array_pop($stack)) {
        if(!is_readable($dir) || !is_writable($dir))
        return false;
        $files = array_diff(scandir($dir), array('.','..'));
        foreach($files as $file) if(is_dir($file)) {
            $stack[] = "$dir/$file";
        }
    }
    return true;
}
function err($code,$msg) {
    echo json_encode(array('error' => array('code'=>intval($code), 'msg' => $msg)));
    exit;
}
function asBytes($ini_v) {
    $ini_v = trim($ini_v);
    $s = array('g'=> 1<<30, 'm' => 1<<20, 'k' => 1<<10);
    return intval($ini_v) * ($s[strtolower(substr($ini_v,-1))] ?: 1);
}
$MAX_UPLOAD_SIZE = min(asBytes(ini_get('post_max_size')), asBytes(ini_get('upload_max_filesize')));
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta name="generator" content="HTML Tidy for Windows (vers 14 February 2006), see www.w3.org">
<title></title>
</head>
<body>
</body>
</html>

One useful guide is there shouldn't be consecutive open '{' or close '}' at the same column.