mirror of
https://github.com/misterunknown/ifm.git
synced 2025-01-16 20:28:26 +01:00
Merge branch 'master' of github.com:novashdima/ifm into novashdima-master
This commit is contained in:
commit
f57ef6a469
164
README.md
164
README.md
@ -1,31 +1,34 @@
|
|||||||
# IFM - improved file manager
|
# IFM - improved file manager
|
||||||
## contents
|
|
||||||
- [about](#about)
|
## Contents
|
||||||
- [features](#features)
|
|
||||||
- [requirements](#requirements)
|
* [about](#about)
|
||||||
- [installation](#installation)
|
* [features](#features)
|
||||||
- [security information](#security-information)
|
* [requirements](#requirements)
|
||||||
- [keybindings](#keybindings)
|
* [installation](#installation)
|
||||||
- [configuration](#configuration)
|
* [security information](#security-information)
|
||||||
- [docker](#docker)
|
* [keybindings](#keybindings)
|
||||||
- [screenshots](#screenshots)
|
* [configuration](#configuration)
|
||||||
- [issues](#issues)
|
* [docker](#docker)
|
||||||
|
* [screenshots](#screenshots)
|
||||||
|
* [issues](#issues)
|
||||||
|
|
||||||
## About
|
## About
|
||||||
The IFM is a web-based filemanager, which comes as a single file solution using
|
|
||||||
HTML5, CSS3, JavaScript and PHP. You can test a [demo
|
|
||||||
here](https://ifmdemo.gitea.de/).
|
|
||||||
|
|
||||||
<a href="https://youtu.be/owJepSas19Y"><img src="https://img.youtube.com/vi/owJepSas19Y/hqdefault.jpg"></a>
|
The IFM is a web-based filemanager, which comes as a single file solution using HTML5, CSS3, JavaScript and PHP. You can test a [demo here](https://ifmdemo.gitea.de/).
|
||||||
|
|
||||||
|
[![IFM](https://img.youtube.com/vi/owJepSas19Y/hqdefault.jpg)](https://youtu.be/owJepSas19Y)
|
||||||
|
|
||||||
The IFM uses the following resources:
|
The IFM uses the following resources:
|
||||||
|
|
||||||
* [ACE Editor](https://ace.c9.io)
|
* [ACE Editor](https://ace.c9.io)
|
||||||
* [Bootstrap v4](https://getbootstrap.com)
|
* [Bootstrap v4](https://getbootstrap.com)
|
||||||
* custom icon set generated with [Fontello](http://fontello.com/)
|
* custom icon set generated with [Fontello](http://fontello.com/)
|
||||||
* [jQuery](https://jquery.com)
|
* [jQuery](https://jquery.com)
|
||||||
* [Mustache](https://mustache.github.io/)
|
* [Mustache](https://mustache.github.io/)
|
||||||
|
|
||||||
## features
|
## Features
|
||||||
|
|
||||||
* create/edit files and directories
|
* create/edit files and directories
|
||||||
* copy/move files and directories
|
* copy/move files and directories
|
||||||
* download files and directories
|
* download files and directories
|
||||||
@ -36,46 +39,40 @@ The IFM uses the following resources:
|
|||||||
* simple authentication (LDAP via `ldap_bind` possible)
|
* simple authentication (LDAP via `ldap_bind` possible)
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
* Client
|
* Client
|
||||||
* HTML5 and CSS3 compatible browser
|
+ HTML5 and CSS3 compatible browser
|
||||||
* activated javascript
|
+ activated javascript
|
||||||
* Server
|
* Server
|
||||||
* PHP >= 5.6
|
+ PHP >= 5.6
|
||||||
* extensions
|
+ extensions
|
||||||
* bz2
|
- bz2
|
||||||
* curl (for remote upload)
|
- curl (for remote upload)
|
||||||
* fileinfo
|
- fileinfo
|
||||||
* json
|
- json
|
||||||
* ldap (only if LDAP based authentication is used)
|
- ldap (only if LDAP based authentication is used)
|
||||||
* mbstring
|
- mbstring
|
||||||
* openssl (for remote uploads from https sources)
|
- openssl (for remote uploads from https sources)
|
||||||
* phar
|
- phar
|
||||||
* posix
|
- posix
|
||||||
* zip
|
- zip
|
||||||
* zlib
|
- zlib
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Just download the latest release of the IFM. You can find it
|
|
||||||
[here](https://github.com/misterunknown/ifm/releases/latest). You can choose
|
|
||||||
between the CDN version (dependencies like bootstrap, jquery etc. are loaded
|
|
||||||
via CDN) or the "simple" version, which bundles all these dependencies.
|
|
||||||
|
|
||||||
The minified versions (`*.min.php`) are zipped via gzip. These versions are not
|
Just download the latest release of the IFM. You can find it [here](https://github.com/misterunknown/ifm/releases/latest). You can choose between the CDN version (dependencies like bootstrap, jquery etc. are loaded via CDN) or the "simple" version, which bundles all these dependencies.
|
||||||
recommended; if the filesize of the IFM is an issue for you, consider using the
|
|
||||||
CDN versions.
|
The minified versions (`*.min.php`) are zipped via gzip. These versions are not recommended; if the filesize of the IFM is an issue for you, consider using the CDN versions.
|
||||||
|
|
||||||
## Security information
|
## Security information
|
||||||
The IFM is usually locked to it's own directory, so you are not able to go
|
|
||||||
above. You can change that by setting the `root_dir` in the scripts
|
|
||||||
[configuration](https://github.com/misterunknown/ifm/wiki/Configuration).
|
|
||||||
|
|
||||||
By default, it is not allowed to show or edit the `.htaccess` file. This is
|
The IFM is usually locked to it's own directory, so you are not able to go above. You can change that by setting the `root_dir` in the scripts [configuration](https://github.com/misterunknown/ifm/wiki/Configuration).
|
||||||
because you can configure the IFM via environment variables. Thus if anyone has
|
|
||||||
the ability to edit the `.htaccess` file, he could overwrite the active
|
By default, it is not allowed to show or edit the `.htaccess` file. This is because you can configure the IFM via environment variables. Thus if anyone has the ability to edit the `.htaccess` file, he could overwrite the active
|
||||||
configuration. [See
|
configuration. [See also](https://github.com/misterunknown/ifm/wiki/Configuration).
|
||||||
also](https://github.com/misterunknown/ifm/wiki/Configuration).
|
|
||||||
|
## Keybindings
|
||||||
|
|
||||||
## Key bindings
|
|
||||||
* <kbd>e</kbd> - edit / extract current file
|
* <kbd>e</kbd> - edit / extract current file
|
||||||
* <kbd>h</kbd><kbd>j</kbd><kbd>k</kbd><kbd>l</kbd> - vim-style navigation (alternative to arrow keys)
|
* <kbd>h</kbd><kbd>j</kbd><kbd>k</kbd><kbd>l</kbd> - vim-style navigation (alternative to arrow keys)
|
||||||
* <kbd>g</kbd> - focus the path input field (i.e. "goto")
|
* <kbd>g</kbd> - focus the path input field (i.e. "goto")
|
||||||
@ -95,55 +92,66 @@ also](https://github.com/misterunknown/ifm/wiki/Configuration).
|
|||||||
* <kbd>Ctrl</kbd>-<kbd>Shift</kbd>-<kbd>f</kbd> - toggle fullscreen ace editor
|
* <kbd>Ctrl</kbd>-<kbd>Shift</kbd>-<kbd>f</kbd> - toggle fullscreen ace editor
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
See [configuration](https://github.com/misterunknown/ifm/wiki/Configuration).
|
See [configuration](https://github.com/misterunknown/ifm/wiki/Configuration).
|
||||||
### authentication
|
|
||||||
|
### Authentication
|
||||||
|
|
||||||
See [authentication](https://github.com/misterunknown/ifm/wiki/Authentication).
|
See [authentication](https://github.com/misterunknown/ifm/wiki/Authentication).
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
The docker image is based on the official php docker images (alpine version)
|
The docker image is based on the official php docker images (alpine version)
|
||||||
and exposes port 80.
|
and exposes port 80.
|
||||||
|
|
||||||
### Quickstart
|
### Quickstart
|
||||||
|
|
||||||
Build the image with this command in the top source dir:
|
Build the image with this command in the top source dir:
|
||||||
|
|
||||||
`docker build -t ifm .`
|
```bash
|
||||||
|
docker build -t ifm .
|
||||||
|
```
|
||||||
|
|
||||||
Afterwards you can start the docker container as follows:
|
Afterwards you can start the docker container as follows:
|
||||||
|
|
||||||
`docker run --rm -d --name ifm -p 8080:80 -v /path/to/data:/var/www ifm:latest`
|
```bash
|
||||||
|
docker run --rm -d --name ifm -p 8080:80 -v /path/to/data:/var/www ifm:latest
|
||||||
### Specify user/group
|
|
||||||
By default IFM runs as user www-data (uid/gid 33). If you need to change that,
|
|
||||||
you can set the UID and GID with the following environment variables:
|
|
||||||
|
|
||||||
`docker run ... -e IFM_DOCKER_UID=1000 -e IFM_DOCKER_GID=100 ifm:latest`
|
|
||||||
|
|
||||||
### Other configuration
|
|
||||||
The script is located at `/usr/local/share/webapps/ifm/index.php`. By default
|
|
||||||
the `root_dir` is set to /var/www, so you can mount any directory at this
|
|
||||||
location. If you want to bind the corresponding host directory, you can do the
|
|
||||||
following:
|
|
||||||
|
|
||||||
`docker run --rm -i -p "8080:80" -v "/var/www:/var/www" ifm`
|
|
||||||
|
|
||||||
The scripts configuration can be changed by adjusting the corresponding
|
|
||||||
environment variables. For example:
|
|
||||||
|
|
||||||
```docker run --rm -i -p "8080:80" -v /var/www:/var/www \
|
|
||||||
-e IFM_AUTH=1 -e IFM_AUTH \
|
|
||||||
-e IFM_AUTH_SOURCE="admin:$2y$05$LPdE7u/5da/TCE8ZhqQ1o.acuV50HqB3OrHhNwxbXYeWmmZKdQxrC" \
|
|
||||||
ifm
|
|
||||||
```
|
```
|
||||||
|
|
||||||
You can get a complete list of environment variables
|
### Specify user/group
|
||||||
[here](https://github.com/misterunknown/ifm/wiki/Configuration#configuration-options).
|
|
||||||
|
By default IFM runs as user www-data (uid/gid 33). If you need to change that, you can set the UID and GID with the following environment variables:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run ... -e IFM_DOCKER_UID=1000 -e IFM_DOCKER_GID=100 ifm:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Other configuration
|
||||||
|
|
||||||
|
The script is located at `/usr/local/share/webapps/ifm/index.php`. By default the `root_dir` is set to /var/www, so you can mount any directory at this location. If you want to bind the corresponding host directory, you can do the following:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm -i -p "8080:80" -v "/var/www:/var/www" ifm
|
||||||
|
```
|
||||||
|
|
||||||
|
The scripts configuration can be changed by adjusting the corresponding environment variables. For example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm -i -p "8080:80" -v /var/www:/var/www \
|
||||||
|
-e IFM_AUTH=1 -e IFM_AUTH \
|
||||||
|
-e IFM_AUTH_SOURCE="admin:$2y$05$LPdE7u/5da/TCE8ZhqQ1o.acuV50HqB3OrHhNwxbXYeWmmZKdQxrC" \
|
||||||
|
ifm
|
||||||
|
```
|
||||||
|
|
||||||
|
You can get a complete list of environment variables [here](https://github.com/misterunknown/ifm/wiki/Configuration#configuration-options).
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
## screenshots
|
|
||||||
<a href="https://misterunknown.de/static/ifm_screenshot_desktop_filelist.png"><img src="https://misterunknown.de/static/ifm_screenshot_desktop_filelist.png" height="300px"></a>
|
<a href="https://misterunknown.de/static/ifm_screenshot_desktop_filelist.png"><img src="https://misterunknown.de/static/ifm_screenshot_desktop_filelist.png" height="300px"></a>
|
||||||
<a href="https://misterunknown.de/static/ifm_screenshot_mobile_filelist.png"><img src="https://misterunknown.de/static/ifm_screenshot_mobile_filelist.png" height="300px"></a>
|
<a href="https://misterunknown.de/static/ifm_screenshot_mobile_filelist.png"><img src="https://misterunknown.de/static/ifm_screenshot_mobile_filelist.png" height="300px"></a>
|
||||||
<a href="https://misterunknown.de/static/ifm_screenshot_desktop_remote_upload.png"><img src="https://misterunknown.de/static/ifm_screenshot_desktop_remote_upload.png" height="300px"></a>
|
<a href="https://misterunknown.de/static/ifm_screenshot_desktop_remote_upload.png"><img src="https://misterunknown.de/static/ifm_screenshot_desktop_remote_upload.png" height="300px"></a>
|
||||||
<a href="https://misterunknown.de/static/ifm_screenshot_mobile_editfile.png"><img src="https://misterunknown.de/static/ifm_screenshot_mobile_editfile.png" height="300px"></a>
|
<a href="https://misterunknown.de/static/ifm_screenshot_mobile_editfile.png"><img src="https://misterunknown.de/static/ifm_screenshot_mobile_editfile.png" height="300px"></a>
|
||||||
|
|
||||||
## issues
|
## Issues
|
||||||
If you happen to find an error or miss a feature, you can create an issue on
|
|
||||||
Github.
|
If you happen to find an error or miss a feature, you can create an issue on Github.
|
39
compiler.php
39
compiler.php
@ -26,16 +26,19 @@ $IFM_SRC_PHP = [
|
|||||||
$options = getopt(null, ["language::", "languages::", "lang::", "cdn"]);
|
$options = getopt(null, ["language::", "languages::", "lang::", "cdn"]);
|
||||||
|
|
||||||
// build CDN version?
|
// build CDN version?
|
||||||
if (isset($options['cdn']))
|
if (isset($options['cdn'])) {
|
||||||
define("IFM_CDN", true);
|
define("IFM_CDN", true);
|
||||||
else
|
} else {
|
||||||
define("IFM_CDN", false);
|
define("IFM_CDN", false);
|
||||||
|
}
|
||||||
|
|
||||||
// process languages
|
// process languages
|
||||||
$langs = [];
|
$langs = [];
|
||||||
foreach ($options as $key => $value)
|
foreach ($options as $key => $value) {
|
||||||
if (substr($key, 0, 4) == "lang")
|
if (substr($key, 0, 4) == "lang") {
|
||||||
$langs = array_merge($langs, explode(",", $value));
|
$langs = array_merge($langs, explode(",", $value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$langs = array_unique($langs);
|
$langs = array_unique($langs);
|
||||||
if (!empty($langs)) {
|
if (!empty($langs)) {
|
||||||
@ -45,25 +48,28 @@ if (!empty($langs)) {
|
|||||||
}
|
}
|
||||||
// ensure english is available, as it gets merged with the other languages
|
// ensure english is available, as it gets merged with the other languages
|
||||||
// in case of missing keys in other languages.
|
// in case of missing keys in other languages.
|
||||||
if (!in_array("all", $langs) || !in_array("en", $langs))
|
if (!in_array("all", $langs) || !in_array("en", $langs)) {
|
||||||
array_push($langs, "en");
|
array_push($langs, "en");
|
||||||
|
}
|
||||||
|
|
||||||
if (in_array("all", $langs))
|
if (in_array("all", $langs))
|
||||||
$langs = array_map(
|
$langs = array_map(
|
||||||
function($lang_file) {return pathinfo($lang_file)['filename']; },
|
function ($lang_file) { return pathinfo($lang_file)['filename']; },
|
||||||
glob("src/i18n/*.json")
|
glob("src/i18n/*.json")
|
||||||
);
|
);
|
||||||
|
|
||||||
$vars['languageincludes'] = "";
|
$vars['languageincludes'] = "";
|
||||||
foreach ($langs as $l)
|
foreach ($langs as $l) {
|
||||||
if (file_exists("src/i18n/".$l.".json"))
|
if (file_exists("src/i18n/".$l.".json")) {
|
||||||
$vars['languageincludes'] .=
|
$vars['languageincludes'] .=
|
||||||
'$i18n["'.$l.'"] = <<<\'f00bar\'' . "\n"
|
'$i18n["'.$l.'"] = <<<\'f00bar\'' . "\n"
|
||||||
. file_get_contents( "src/i18n/".$l.".json" ) . "\n"
|
. file_get_contents( "src/i18n/".$l.".json" ) . "\n"
|
||||||
. 'f00bar;' . "\n"
|
. 'f00bar;' . "\n"
|
||||||
. '$i18n["'.$l.'"] = json_decode( $i18n["'.$l.'"], true );' . "\n" ;
|
. '$i18n["'.$l.'"] = json_decode( $i18n["'.$l.'"], true );' . "\n" ;
|
||||||
else
|
} else {
|
||||||
print "WARNING: Language file src/i18n/".$l.".json not found.\n";
|
print "WARNING: Language file src/i18n/".$l.".json not found.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Concat PHP Files
|
// Concat PHP Files
|
||||||
$compiled = ["<?php"];
|
$compiled = ["<?php"];
|
||||||
@ -81,11 +87,12 @@ $compiled = str_replace("###ASSETS_JS###", file_get_contents("src/assets".(IFM_C
|
|||||||
// Process file includes
|
// Process file includes
|
||||||
$includes = NULL;
|
$includes = NULL;
|
||||||
preg_match_all("/\#\#\#file:([^\#]+)\#\#\#/", $compiled, $includes, PREG_SET_ORDER);
|
preg_match_all("/\#\#\#file:([^\#]+)\#\#\#/", $compiled, $includes, PREG_SET_ORDER);
|
||||||
foreach ($includes as $file)
|
foreach ($includes as $file) {
|
||||||
$compiled = str_replace($file[0], file_get_contents($file[1]), $compiled);
|
$compiled = str_replace($file[0], file_get_contents($file[1]), $compiled);
|
||||||
|
}
|
||||||
|
|
||||||
// Process ace includes
|
// Process ace includes
|
||||||
$includes = NULL;
|
$includes = null;
|
||||||
$vars['ace_includes'] = "";
|
$vars['ace_includes'] = "";
|
||||||
preg_match_all("/\#\#\#acedir:([^\#]+)\#\#\#/", $compiled, $includes, PREG_SET_ORDER);
|
preg_match_all("/\#\#\#acedir:([^\#]+)\#\#\#/", $compiled, $includes, PREG_SET_ORDER);
|
||||||
foreach ($includes as $dir) {
|
foreach ($includes as $dir) {
|
||||||
@ -102,13 +109,15 @@ foreach ($includes as $dir) {
|
|||||||
// Process variable includes
|
// Process variable includes
|
||||||
$includes = NULL;
|
$includes = NULL;
|
||||||
preg_match_all("/\#\#\#vars:([^\#]+)\#\#\#/", $compiled, $includes, PREG_SET_ORDER);
|
preg_match_all("/\#\#\#vars:([^\#]+)\#\#\#/", $compiled, $includes, PREG_SET_ORDER);
|
||||||
foreach( $includes as $var )
|
foreach( $includes as $var ) {
|
||||||
$compiled = str_replace($var[0], $vars[$var[1]], $compiled);
|
$compiled = str_replace($var[0], $vars[$var[1]], $compiled);
|
||||||
|
}
|
||||||
|
|
||||||
$compiled = str_replace('IFM_VERSION', IFM_VERSION, $compiled);
|
$compiled = str_replace('IFM_VERSION', IFM_VERSION, $compiled);
|
||||||
|
|
||||||
if (!is_dir(IFM_RELEASE_DIR))
|
if (!is_dir(IFM_RELEASE_DIR)) {
|
||||||
mkdir(IFM_RELEASE_DIR);
|
mkdir(IFM_RELEASE_DIR);
|
||||||
|
}
|
||||||
|
|
||||||
// build standalone ifm
|
// build standalone ifm
|
||||||
file_put_contents(IFM_RELEASE_DIR . (IFM_CDN ? 'cdn.' : '') . IFM_STANDALONE, $compiled);
|
file_put_contents(IFM_RELEASE_DIR . (IFM_CDN ? 'cdn.' : '') . IFM_STANDALONE, $compiled);
|
||||||
@ -123,7 +132,7 @@ $ifm->run();
|
|||||||
// build compressed ifm
|
// build compressed ifm
|
||||||
file_put_contents(
|
file_put_contents(
|
||||||
IFM_RELEASE_DIR . (IFM_CDN ? 'cdn.' : '') . IFM_STANDALONE_GZ,
|
IFM_RELEASE_DIR . (IFM_CDN ? 'cdn.' : '') . IFM_STANDALONE_GZ,
|
||||||
'<?php eval( gzdecode( file_get_contents( __FILE__, false, null, 85 ) ) ); exit(0); ?>'
|
'<?php eval(gzdecode(file_get_contents(__FILE__, false, null, 85))); exit(0); ?>'
|
||||||
. gzencode(file_get_contents(IFM_RELEASE_DIR . (IFM_CDN ? 'cdn.' : '') . IFM_STANDALONE, false, null, 5))
|
. gzencode(file_get_contents(IFM_RELEASE_DIR . (IFM_CDN ? 'cdn.' : '') . IFM_STANDALONE, false, null, 5))
|
||||||
);
|
);
|
||||||
// build lib
|
// build lib
|
||||||
|
@ -3,30 +3,30 @@ set -e
|
|||||||
|
|
||||||
if [ ! -z $IFM_DOCKER_UID ]; then
|
if [ ! -z $IFM_DOCKER_UID ]; then
|
||||||
# check if UID/GID are numeric
|
# check if UID/GID are numeric
|
||||||
if ! echo "$IFM_DOCKER_UID$IFM_DOCKER_GID" | egrep "^[0-9]+$" >/dev/null 2>&1; then
|
if ! echo "$IFM_DOCKER_UID$IFM_DOCKER_GID" | grep -E "^[0-9]+$" >/dev/null 2>&1; then
|
||||||
echo "FATAL: IFM_DOCKER_UID or IFM_DOCKER_GID are not numeric (UID: $IFM_DOCKER_UID, GID: $IFM_DOCKER_GID)"
|
echo "FATAL: IFM_DOCKER_UID or IFM_DOCKER_GID are not numeric (UID: $IFM_DOCKER_UID, GID: $IFM_DOCKER_GID)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# get GID if not set
|
# get GID if not set
|
||||||
if [ -z $IFM_DOCKER_GID ]; then
|
if [ -z "$IFM_DOCKER_GID" ]; then
|
||||||
export IFM_DOCKER_GID=$IFM_DOCKER_UID
|
export IFM_DOCKER_GID="$IFM_DOCKER_UID"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# delete user if already exists
|
# delete user if already exists
|
||||||
if getent passwd $IFM_DOCKER_UID >/dev/null 2>&1; then
|
if getent passwd "$IFM_DOCKER_UID" >/dev/null 2>&1; then
|
||||||
deluser $(getent passwd $IFM_DOCKER_UID | sed "s/:.*//")
|
deluser $(getent passwd "$IFM_DOCKER_UID" | sed "s/:.*//")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# check if group already exists
|
# check if group already exists
|
||||||
if ! getent group $IFM_DOCKER_GID >/dev/null 2>&1; then
|
if ! getent group "$IFM_DOCKER_GID" >/dev/null 2>&1; then
|
||||||
addgroup -g $IFM_DOCKER_GID -S www-data
|
addgroup -g "$IFM_DOCKER_GID" -S www-data
|
||||||
REAL_GROUP=www-data
|
REAL_GROUP=www-data
|
||||||
else
|
else
|
||||||
REAL_GROUP=$(getent group $IFM_DOCKER_GID | sed "s/:.*//")
|
REAL_GROUP=$(getent group "$IFM_DOCKER_GID" | sed "s/:.*//")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
adduser -u $IFM_DOCKER_UID -SHDG $REAL_GROUP www-data
|
adduser -u "$IFM_DOCKER_UID" -SHDG "$REAL_GROUP" www-data
|
||||||
else
|
else
|
||||||
addgroup -g 33 -S www-data
|
addgroup -g 33 -S www-data
|
||||||
adduser -SHD -u 33 -G www-data www-data
|
adduser -SHD -u 33 -G www-data www-data
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.1/css/bootstrap.min.css" integrity="sha512-T584yQ/tdRR5QwOpfvDfVQUidzfgc2339Lc8uBDtcp/wYu80d7jwBgAxbyMh0a9YM9F8N3tdErpFI8iaGx6x5g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap.min.css" integrity="sha512-rt/SrQ4UNIaGfDyEXZtNcyWvQeOq0QLygHluFQcSjaGB04IxWhal71tKuzP6K8eYXYB6vJV4pHkXcmFGGQ1/0w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||||
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs4/dt-1.11.3/r-2.2.9/datatables.min.css"/>
|
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs4/dt-1.13.1/r-2.4.0/datatables.min.css"/>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
###file:src/includes/bootstrap-treeview.min.css###
|
###file:src/includes/bootstrap-treeview.min.css###
|
||||||
###file:src/includes/fontello-embedded.css###
|
###file:src/includes/fontello-embedded.css###
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js" integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.1/umd/popper.min.js" integrity="sha512-ubuT8Z88WxezgSqf3RLuNi5lmjstiJcyezx34yIU2gAHonIi27Na7atqzUZCOoY4CExaoFumzOsFQ2Ch+I/HCw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.1/umd/popper.min.js" integrity="sha512-ubuT8Z88WxezgSqf3RLuNi5lmjstiJcyezx34yIU2gAHonIi27Na7atqzUZCOoY4CExaoFumzOsFQ2Ch+I/HCw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.1/js/bootstrap.min.js" integrity="sha512-UR25UO94eTnCVwjbXozyeVd6ZqpaAE9naiEUBK/A+QDbfSTQFhPGj5lOR6d8tsgbBk84Ggb5A3EkjsOgPRPcKA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/js/bootstrap.min.js" integrity="sha512-7rusk8kGPFynZWu26OKbTeI+QPoYchtxsmPeBqkHIEXJxeun4yJ4ISYe7C6sz9wdxeE1Gk3VxsIWgCZTc+vX3g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.11.3/r-2.2.9/datatables.min.js"></script>
|
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.13.1/r-2.4.0/datatables.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/classnames/2.3.1/index.min.js" integrity="sha512-6Wf/IjsSjLaFTYco3pXM+49kC5M7jtbHzxMcdmYvwDskjv7cMcBPmJX2053aoQ+LRi8Po4ZsCtkNMf+NhXhNyQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script async src="https://cdnjs.cloudflare.com/ajax/libs/classnames/2.3.2/index.min.js" integrity="sha512-GqhSAi+WYQlHmNWiE4TQsVa7HVKctQMdgUMA+1RogjxOPdv9Kj59/no5BEvJgpvuMTYw2JRQu/szumfVXdowag==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/3.2.1/mustache.min.js" integrity="sha512-Qjrukx28QnvFWISw9y4wCB0kTB/ISnWXPz5/RME5o8OlZqllWygc1AB64dOBlngeTeStmYmNTNcM6kfEjUdnnQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/3.2.1/mustache.min.js" integrity="sha512-Qjrukx28QnvFWISw9y4wCB0kTB/ISnWXPz5/RME5o8OlZqllWygc1AB64dOBlngeTeStmYmNTNcM6kfEjUdnnQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/mouse0270-bootstrap-notify/3.1.7/bootstrap-notify.min.js" integrity="sha512-BUaP7iu0aHqAISI8LphJT07Rv/MOiPI+mmq0h1rckNbzuKAW+UqmwEANqLPqanKNU331yApBM+40pZIkwkWAEQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/mouse0270-bootstrap-notify/3.1.7/bootstrap-notify.min.js" integrity="sha512-BUaP7iu0aHqAISI8LphJT07Rv/MOiPI+mmq0h1rckNbzuKAW+UqmwEANqLPqanKNU331yApBM+40pZIkwkWAEQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" integrity="sha512-uto9mlQzrs59VwILcLiRYeLKPPbS/bT71da/OEBYEwcdNUk8jYIy+D176RYoop1Da+f9mvkYrmj5MCLZWEtQuA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js" integrity="sha512-57oZ/vW8ANMjR/KQ6Be9v/+/h6bq9/l3f0Oc7vn6qMqyhvPd1cvKBRWWpzu0QoneImqr2SkmO4MSqU+RpHom3Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.13/ace.min.js" integrity="sha512-jB1NOQkR0yLnWmEZQTUW4REqirbskxoYNltZE+8KzXqs9gHG5mrxLR5w3TwUn6AylXkhZZWTPP894xcX/X8Kbg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.14.0/ace.min.js" integrity="sha512-s57ywpCtz+4PU992Bg1rDtr6+1z38gO2mS92agz2nqQcuMQ6IvgLWoQ2SFpImvg1rbgqBKeSEq0d9bo9NtBY0w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
<script defer>
|
<script defer>
|
||||||
###file:src/includes/bootstrap-treeview.min.js###
|
###file:src/includes/bootstrap-treeview.min.js###
|
||||||
###file:src/includes/BootstrapMenu.min.js###
|
###file:src/includes/BootstrapMenu.min.js###
|
||||||
|
187
src/htpasswd.php
187
src/htpasswd.php
@ -6,53 +6,55 @@
|
|||||||
class Htpasswd {
|
class Htpasswd {
|
||||||
public $users = [];
|
public $users = [];
|
||||||
|
|
||||||
public function __construct( $filename="" ) {
|
public function __construct($filename="") {
|
||||||
if( $filename )
|
if ($filename) {
|
||||||
$this->load( $filename );
|
$this->load($filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a new htpasswd file
|
* Load a new htpasswd file
|
||||||
*/
|
*/
|
||||||
public function load( $filename ) {
|
public function load($filename) {
|
||||||
unset( $this->users );
|
unset($this->users);
|
||||||
if( file_exists( $filename ) && is_readable( $filename ) ) {
|
if (file_exists($filename) && is_readable($filename)) {
|
||||||
$lines = file( $filename );
|
$lines = file( $filename );
|
||||||
foreach( $lines as $line ) {
|
foreach ($lines as $line) {
|
||||||
list( $user, $pass ) = explode( ":", $line );
|
list($user, $pass) = explode(":", $line);
|
||||||
$this->users[$user] = trim( $pass );
|
$this->users[$user] = trim($pass);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUsers() {
|
|
||||||
return array_keys( $this->users );
|
|
||||||
}
|
|
||||||
|
|
||||||
public function userExist( $user ) {
|
|
||||||
return isset( $this->users[ $user ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
public function verify( $user, $pass ) {
|
|
||||||
if( isset( $this->users[$user] ) ) {
|
|
||||||
return $this->verifyPassword( $pass, $this->users[$user] );
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function verifyPassword( $pass, $hash ) {
|
public function getUsers() {
|
||||||
if( substr( $hash, 0, 4 ) == '$2y$' ) {
|
return array_keys($this->users);
|
||||||
return password_verify( $pass, $hash );
|
}
|
||||||
} elseif( substr( $hash, 0, 6 ) == '$apr1$' ) {
|
|
||||||
|
public function userExist($user) {
|
||||||
|
return isset($this->users[$user]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verify($user, $pass) {
|
||||||
|
if (isset($this->users[$user])) {
|
||||||
|
return $this->verifyPassword($pass, $this->users[$user]);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verifyPassword($pass, $hash) {
|
||||||
|
if (substr($hash, 0, 4) == '$2y$') {
|
||||||
|
return password_verify($pass, $hash);
|
||||||
|
} elseif (substr($hash, 0, 6) == '$apr1$') {
|
||||||
$apr1 = new APR1_MD5();
|
$apr1 = new APR1_MD5();
|
||||||
return $apr1->check( $pass, $hash );
|
return $apr1->check($pass, $hash);
|
||||||
} elseif( substr( $hash, 0, 5 ) == '{SHA}' ) {
|
} elseif (substr($hash, 0, 5) == '{SHA}') {
|
||||||
return base64_encode( sha1( $pass, TRUE ) ) == substr( $hash, 5 );
|
return base64_encode(sha1($pass, true)) == substr($hash, 5);
|
||||||
} else { // assume CRYPT
|
} else { // assume CRYPT
|
||||||
return crypt( $pass, $hash ) == $hash;
|
return crypt($pass, $hash) == $hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,64 +66,73 @@ class Htpasswd {
|
|||||||
*/
|
*/
|
||||||
class APR1_MD5 {
|
class APR1_MD5 {
|
||||||
|
|
||||||
const BASE64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
const BASE64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||||
const APRMD5_ALPHABET = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
const APRMD5_ALPHABET = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
||||||
|
|
||||||
// Source/References for core algorithm:
|
// Source/References for core algorithm:
|
||||||
// http://www.cryptologie.net/article/126/bruteforce-apr1-hashes/
|
// http://www.cryptologie.net/article/126/bruteforce-apr1-hashes/
|
||||||
// http://svn.apache.org/viewvc/apr/apr-util/branches/1.3.x/crypto/apr_md5.c?view=co
|
// http://svn.apache.org/viewvc/apr/apr-util/branches/1.3.x/crypto/apr_md5.c?view=co
|
||||||
// http://www.php.net/manual/en/function.crypt.php#73619
|
// http://www.php.net/manual/en/function.crypt.php#73619
|
||||||
// http://httpd.apache.org/docs/2.2/misc/password_encryptions.html
|
// http://httpd.apache.org/docs/2.2/misc/password_encryptions.html
|
||||||
// Wikipedia
|
// Wikipedia
|
||||||
|
|
||||||
public static function hash($mdp, $salt = null) {
|
public static function hash($mdp, $salt = null) {
|
||||||
if (is_null($salt))
|
if (is_null($salt)) {
|
||||||
$salt = self::salt();
|
$salt = self::salt();
|
||||||
$salt = substr($salt, 0, 8);
|
}
|
||||||
$max = strlen($mdp);
|
$salt = substr($salt, 0, 8);
|
||||||
$context = $mdp.'$apr1$'.$salt;
|
$max = strlen($mdp);
|
||||||
$binary = pack('H32', md5($mdp.$salt.$mdp));
|
$context = $mdp.'$apr1$'.$salt;
|
||||||
for($i=$max; $i>0; $i-=16)
|
$binary = pack('H32', md5($mdp.$salt.$mdp));
|
||||||
$context .= substr($binary, 0, min(16, $i));
|
for ($i=$max; $i>0; $i-=16) {
|
||||||
for($i=$max; $i>0; $i>>=1)
|
$context .= substr($binary, 0, min(16, $i));
|
||||||
$context .= ($i & 1) ? chr(0) : $mdp[0];
|
}
|
||||||
$binary = pack('H32', md5($context));
|
for ($i=$max; $i>0; $i>>=1) {
|
||||||
for($i=0; $i<1000; $i++) {
|
$context .= ($i & 1) ? chr(0) : $mdp[0];
|
||||||
$new = ($i & 1) ? $mdp : $binary;
|
}
|
||||||
if($i % 3) $new .= $salt;
|
$binary = pack('H32', md5($context));
|
||||||
if($i % 7) $new .= $mdp;
|
for ($i=0; $i<1000; $i++) {
|
||||||
$new .= ($i & 1) ? $binary : $mdp;
|
$new = ($i & 1) ? $mdp : $binary;
|
||||||
$binary = pack('H32', md5($new));
|
if ($i % 3) {
|
||||||
}
|
$new .= $salt;
|
||||||
$hash = '';
|
}
|
||||||
for ($i = 0; $i < 5; $i++) {
|
if ($i % 7) {
|
||||||
$k = $i+6;
|
$new .= $mdp;
|
||||||
$j = $i+12;
|
}
|
||||||
if($j == 16) $j = 5;
|
$new .= ($i & 1) ? $binary : $mdp;
|
||||||
$hash = $binary[$i].$binary[$k].$binary[$j].$hash;
|
$binary = pack('H32', md5($new));
|
||||||
}
|
}
|
||||||
$hash = chr(0).chr(0).$binary[11].$hash;
|
$hash = '';
|
||||||
$hash = strtr(
|
for ($i = 0; $i < 5; $i++) {
|
||||||
strrev(substr(base64_encode($hash), 2)),
|
$k = $i+6;
|
||||||
self::BASE64_ALPHABET,
|
$j = $i+12;
|
||||||
self::APRMD5_ALPHABET
|
if ($j == 16) {
|
||||||
);
|
$j = 5;
|
||||||
return '$apr1$'.$salt.'$'.$hash;
|
}
|
||||||
}
|
$hash = $binary[$i].$binary[$k].$binary[$j].$hash;
|
||||||
|
}
|
||||||
|
$hash = chr(0).chr(0).$binary[11].$hash;
|
||||||
|
$hash = strtr(
|
||||||
|
strrev(substr(base64_encode($hash), 2)),
|
||||||
|
self::BASE64_ALPHABET,
|
||||||
|
self::APRMD5_ALPHABET
|
||||||
|
);
|
||||||
|
return '$apr1$'.$salt.'$'.$hash;
|
||||||
|
}
|
||||||
|
|
||||||
// 8 character salts are the best. Don't encourage anything but the best.
|
// 8 character salts are the best. Don't encourage anything but the best.
|
||||||
public static function salt() {
|
public static function salt() {
|
||||||
$alphabet = self::APRMD5_ALPHABET;
|
$alphabet = self::APRMD5_ALPHABET;
|
||||||
$salt = '';
|
$salt = '';
|
||||||
for($i=0; $i<8; $i++) {
|
for ($i=0; $i<8; $i++) {
|
||||||
$offset = hexdec(bin2hex(openssl_random_pseudo_bytes(1))) % 64;
|
$offset = hexdec(bin2hex(openssl_random_pseudo_bytes(1))) % 64;
|
||||||
$salt .= $alphabet[$offset];
|
$salt .= $alphabet[$offset];
|
||||||
}
|
}
|
||||||
return $salt;
|
return $salt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function check($plain, $hash) {
|
public static function check($plain, $hash) {
|
||||||
$parts = explode('$', $hash);
|
$parts = explode('$', $hash);
|
||||||
return self::hash($plain, $parts[2]) === $hash;
|
return self::hash($plain, $parts[2]) === $hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1399,7 +1399,7 @@ function IFM(params) {
|
|||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
this.inArray = function(needle, haystack) {
|
this.inArray = function(needle, haystack) {
|
||||||
for( let i = 0; i < haystack.length; i++ )
|
for ( let i = 0; i < haystack.length; i++ )
|
||||||
if( haystack[i] == needle )
|
if( haystack[i] == needle )
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
@ -1575,7 +1575,7 @@ function IFM(params) {
|
|||||||
this.generateGuid = function() {
|
this.generateGuid = function() {
|
||||||
let result, i, j;
|
let result, i, j;
|
||||||
result = '';
|
result = '';
|
||||||
for( j = 0; j < 20; j++ ) {
|
for ( j = 0; j < 20; j++ ) {
|
||||||
i = Math.floor( Math.random() * 16 ).toString( 16 ).toUpperCase();
|
i = Math.floor( Math.random() * 16 ).toString( 16 ).toUpperCase();
|
||||||
result = result + i;
|
result = result + i;
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,9 @@ class IFMArchive {
|
|||||||
* Add a folder to an archive
|
* Add a folder to an archive
|
||||||
*/
|
*/
|
||||||
private static function addFolder(&$archive, $folder, $offset=0, $exclude_callback=null) {
|
private static function addFolder(&$archive, $folder, $offset=0, $exclude_callback=null) {
|
||||||
if ($offset == 0)
|
if ($offset == 0) {
|
||||||
$offset = strlen(dirname($folder)) + 1;
|
$offset = strlen(dirname($folder)) + 1;
|
||||||
|
}
|
||||||
$archive->addEmptyDir(substr($folder, $offset));
|
$archive->addEmptyDir(substr($folder, $offset));
|
||||||
$handle = opendir($folder);
|
$handle = opendir($folder);
|
||||||
while (false !== $f = readdir($handle)) {
|
while (false !== $f = readdir($handle)) {
|
||||||
@ -33,13 +34,15 @@ class IFMArchive {
|
|||||||
$filePath = $folder . '/' . $f;
|
$filePath = $folder . '/' . $f;
|
||||||
if (file_exists($filePath) && is_readable($filePath)) {
|
if (file_exists($filePath) && is_readable($filePath)) {
|
||||||
if (is_file($filePath)) {
|
if (is_file($filePath)) {
|
||||||
if (!is_callable($exclude_callback) || $exclude_callback($f))
|
if (!is_callable($exclude_callback) || $exclude_callback($f)) {
|
||||||
$archive->addFile( $filePath, substr( $filePath, $offset ) );
|
$archive->addFile($filePath, substr($filePath, $offset));
|
||||||
|
}
|
||||||
} elseif (is_dir($filePath)) {
|
} elseif (is_dir($filePath)) {
|
||||||
if (is_callable($exclude_callback))
|
if (is_callable($exclude_callback)) {
|
||||||
self::addFolder($archive, $filePath, $offset, $exclude_callback);
|
self::addFolder($archive, $filePath, $offset, $exclude_callback);
|
||||||
else
|
} else {
|
||||||
self::addFolder($archive, $filePath, $offset);
|
self::addFolder($archive, $filePath, $offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,18 +57,22 @@ class IFMArchive {
|
|||||||
$a = new ZipArchive();
|
$a = new ZipArchive();
|
||||||
$a->open($archivename, ZIPARCHIVE::CREATE);
|
$a->open($archivename, ZIPARCHIVE::CREATE);
|
||||||
|
|
||||||
if (!is_array($filenames))
|
if (!is_array($filenames)) {
|
||||||
$filenames = array($filenames);
|
$filenames = array($filenames);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($filenames as $f)
|
foreach ($filenames as $f)
|
||||||
if (is_dir($f))
|
if (is_dir($f)) {
|
||||||
if (is_callable($exclude_callback))
|
if (is_callable($exclude_callback)) {
|
||||||
self::addFolder( $a, $f, null, $exclude_callback );
|
self::addFolder($a, $f, null, $exclude_callback);
|
||||||
else
|
} else {
|
||||||
self::addFolder( $a, $f );
|
self::addFolder($a, $f);
|
||||||
elseif (is_file($f))
|
}
|
||||||
if (!is_callable($exclude_callback) || $exclude_callback($f))
|
} elseif (is_file($f)) {
|
||||||
|
if (!is_callable($exclude_callback) || $exclude_callback($f)) {
|
||||||
$a->addFile($f, pathinfo($f, PATHINFO_BASENAME));
|
$a->addFile($f, pathinfo($f, PATHINFO_BASENAME));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return $a->close();
|
return $a->close();
|
||||||
@ -78,16 +85,18 @@ class IFMArchive {
|
|||||||
* Unzip a zip file
|
* Unzip a zip file
|
||||||
*/
|
*/
|
||||||
public static function extractZip($file, $destination="./") {
|
public static function extractZip($file, $destination="./") {
|
||||||
if (!file_exists($file))
|
if (!file_exists($file)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
$zip = new ZipArchive;
|
$zip = new ZipArchive;
|
||||||
$res = $zip->open($file);
|
$res = $zip->open($file);
|
||||||
if ($res === true) {
|
if ($res === true) {
|
||||||
$zip->extractTo($destination);
|
$zip->extractTo($destination);
|
||||||
$zip->close();
|
$zip->close();
|
||||||
return true;
|
return true;
|
||||||
} else
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,14 +107,17 @@ class IFMArchive {
|
|||||||
$a = new PharData($tmpf);
|
$a = new PharData($tmpf);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!is_array($filenames))
|
if (!is_array($filenames)) {
|
||||||
$filenames = array($filenames);
|
$filenames = array($filenames);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($filenames as $f)
|
foreach ($filenames as $f) {
|
||||||
if (is_dir($f))
|
if (is_dir($f)) {
|
||||||
self::addFolder($a, $f);
|
self::addFolder($a, $f);
|
||||||
elseif (is_file($f))
|
} elseif (is_file($f)) {
|
||||||
$a->addFile($f, pathinfo($f, PATHINFO_BASENAME));
|
$a->addFile($f, pathinfo($f, PATHINFO_BASENAME));
|
||||||
|
}
|
||||||
|
}
|
||||||
switch ($format) {
|
switch ($format) {
|
||||||
case "tar.gz":
|
case "tar.gz":
|
||||||
$a->compress(Phar::GZ);
|
$a->compress(Phar::GZ);
|
||||||
@ -127,8 +139,9 @@ class IFMArchive {
|
|||||||
* Extracts a tar archive
|
* Extracts a tar archive
|
||||||
*/
|
*/
|
||||||
public static function extractTar($file, $destination="./") {
|
public static function extractTar($file, $destination="./") {
|
||||||
if (!file_exists($file))
|
if (!file_exists($file)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
$tar = new PharData($file);
|
$tar = new PharData($file);
|
||||||
try {
|
try {
|
||||||
$tar->extractTo($destination, null, true);
|
$tar->extractTo($destination, null, true);
|
||||||
|
2
src/includes/ace.min.js
vendored
2
src/includes/ace.min.js
vendored
File diff suppressed because one or more lines are too long
8
src/includes/bootstrap.min.css
vendored
8
src/includes/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
6
src/includes/bootstrap.min.js
vendored
6
src/includes/bootstrap.min.js
vendored
File diff suppressed because one or more lines are too long
2
src/includes/classnames.min.js
vendored
2
src/includes/classnames.min.js
vendored
@ -1 +1 @@
|
|||||||
!function(){"use strict";var f={}.hasOwnProperty;function s(){for(var e=[],t=0;t<arguments.length;t++){var n=arguments[t];if(n){var r,o=typeof n;if("string"==o||"number"==o)e.push(n);else if(Array.isArray(n))!n.length||(r=s.apply(null,n))&&e.push(r);else if("object"==o)if(n.toString===Object.prototype.toString)for(var i in n)f.call(n,i)&&n[i]&&e.push(i);else e.push(n.toString())}}return e.join(" ")}"undefined"!=typeof module&&module.exports?(s.default=s,module.exports=s):"function"==typeof define&&"object"==typeof define.amd&&define.amd?define("classnames",[],function(){return s}):window.classNames=s}();
|
!function(){"use strict";var f={}.hasOwnProperty;function s(){for(var e=[],t=0;t<arguments.length;t++){var n=arguments[t];if(n){var o,r=typeof n;if("string"==r||"number"==r)e.push(n);else if(Array.isArray(n))!n.length||(o=s.apply(null,n))&&e.push(o);else if("object"==r)if(n.toString===Object.prototype.toString||n.toString.toString().includes("[native code]"))for(var i in n)f.call(n,i)&&n[i]&&e.push(i);else e.push(n.toString())}}return e.join(" ")}"undefined"!=typeof module&&module.exports?module.exports=s.default=s:"function"==typeof define&&"object"==typeof define.amd&&define.amd?define("classnames",[],function(){return s}):window.classNames=s}();
|
6
src/includes/datatables.min.css
vendored
6
src/includes/datatables.min.css
vendored
File diff suppressed because one or more lines are too long
285
src/includes/datatables.min.js
vendored
285
src/includes/datatables.min.js
vendored
File diff suppressed because one or more lines are too long
13
src/includes/jquery-ui.min.js
vendored
13
src/includes/jquery-ui.min.js
vendored
File diff suppressed because one or more lines are too long
4
src/includes/jquery.min.js
vendored
4
src/includes/jquery.min.js
vendored
File diff suppressed because one or more lines are too long
16
src/main.php
16
src/main.php
@ -220,7 +220,7 @@ f00bar;
|
|||||||
case "getFolders":
|
case "getFolders":
|
||||||
return $this->getFolders($_REQUEST);
|
return $this->getFolders($_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
// checking working directory
|
// checking working directory
|
||||||
if (!isset($_REQUEST["dir"]) || !$this->isPathValid($_REQUEST["dir"]))
|
if (!isset($_REQUEST["dir"]) || !$this->isPathValid($_REQUEST["dir"]))
|
||||||
throw new IFMException($this->l("invalid_dir"));
|
throw new IFMException($this->l("invalid_dir"));
|
||||||
@ -580,7 +580,7 @@ f00bar;
|
|||||||
if (isset($d['filename']) && $this->isFilenameValid($d['filename'])) {
|
if (isset($d['filename']) && $this->isFilenameValid($d['filename'])) {
|
||||||
if (isset($d['content'])) {
|
if (isset($d['content'])) {
|
||||||
// work around magic quotes
|
// work around magic quotes
|
||||||
if((function_exists("get_magic_quotes_gpc") && get_magic_quotes_gpc())
|
if ((function_exists("get_magic_quotes_gpc") && get_magic_quotes_gpc())
|
||||||
|| (ini_get('magic_quotes_sybase') && (strtolower(ini_get('magic_quotes_sybase'))!="off")) ) {
|
|| (ini_get('magic_quotes_sybase') && (strtolower(ini_get('magic_quotes_sybase'))!="off")) ) {
|
||||||
$content = stripslashes($d['content']);
|
$content = stripslashes($d['content']);
|
||||||
} else {
|
} else {
|
||||||
@ -1025,7 +1025,7 @@ f00bar;
|
|||||||
if ($login_failed === true)
|
if ($login_failed === true)
|
||||||
throw new IFMException("Authentication failed: Wrong credentials", true);
|
throw new IFMException("Authentication failed: Wrong credentials", true);
|
||||||
else
|
else
|
||||||
throw new IFMException("Not authenticated" , true);
|
throw new IFMException("Not authenticated", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1058,7 +1058,7 @@ f00bar;
|
|||||||
}
|
}
|
||||||
$u = $uuid . "=" . $user . "," . $basedn;
|
$u = $uuid . "=" . $user . "," . $basedn;
|
||||||
if (!$ds = ldap_connect($ldap_server)) {
|
if (!$ds = ldap_connect($ldap_server)) {
|
||||||
throw new IFMException("Could not reach the ldap server." , true);
|
throw new IFMException("Could not reach the ldap server.", true);
|
||||||
//trigger_error("Could not reach the ldap server.", E_USER_ERROR);
|
//trigger_error("Could not reach the ldap server.", E_USER_ERROR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1070,14 +1070,14 @@ f00bar;
|
|||||||
if (ldap_count_entries($ds, ldap_search($ds, $u, $ufilter)) == 1) {
|
if (ldap_count_entries($ds, ldap_search($ds, $u, $ufilter)) == 1) {
|
||||||
$authenticated = true;
|
$authenticated = true;
|
||||||
} else {
|
} else {
|
||||||
throw new IFMException("User not allowed." , true);
|
throw new IFMException("User not allowed.", true);
|
||||||
//trigger_error("User not allowed.", E_USER_ERROR);
|
//trigger_error("User not allowed.", E_USER_ERROR);
|
||||||
$authenticated = false;
|
$authenticated = false;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
$authenticated = true;
|
$authenticated = true;
|
||||||
} else {
|
} else {
|
||||||
throw new IFMException(ldap_error($ds) , true);
|
throw new IFMException(ldap_error($ds), true);
|
||||||
//trigger_error(ldap_error($ds), E_USER_ERROR);
|
//trigger_error(ldap_error($ds), E_USER_ERROR);
|
||||||
$authenticated = false;
|
$authenticated = false;
|
||||||
}
|
}
|
||||||
@ -1105,7 +1105,7 @@ f00bar;
|
|||||||
private function isAbsolutePath($path) {
|
private function isAbsolutePath($path) {
|
||||||
if ($path === null || $path === '')
|
if ($path === null || $path === '')
|
||||||
return false;
|
return false;
|
||||||
return $path[0] === DIRECTORY_SEPARATOR || preg_match('~^[A-Z]:(?![^/\\\\])~i',$path) > 0;
|
return $path[0] === DIRECTORY_SEPARATOR || preg_match('~^[A-Z]:(?![^/\\\\])~i', $path) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getRootDir() {
|
private function getRootDir() {
|
||||||
@ -1247,7 +1247,7 @@ f00bar;
|
|||||||
$ret = "";
|
$ret = "";
|
||||||
foreach ($parts as $part)
|
foreach ($parts as $part)
|
||||||
if (trim($part) != "")
|
if (trim($part) != "")
|
||||||
$ret .= (empty($ret) ? rtrim($part,"/") : trim($part, '/'))."/";
|
$ret .= (empty($ret) ? rtrim($part, "/") : trim($part, '/'))."/";
|
||||||
return rtrim($ret, "/");
|
return rtrim($ret, "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user