Compare commits

...

4 Commits

6 changed files with 38 additions and 48 deletions

View File

@ -14,7 +14,7 @@ Dexter depends on these Perl modules:
Install them using `cpan` or however else you get your Perl modules.
Once the proper modules are installed, drop the contents of `app/` into whichever directory you keep your webapps and scripts in.
Once the proper modules are installed, clone this repository to wherever you want Dexter to reside. For me on my OpenBSD web server, that's `/var/www/cgi-bin/`.
After that, Dexter can be ran under any web server as a CGI or PSGI app, or via Mojolicious' builtin `morbo` and `hypnotoad` servers. See `examples/openbsd/etc/` for the configuration files that I use on my OpenBSD web server to connect Dexter with `httpd`.
@ -37,4 +37,4 @@ Dexter needs to know about two directories you want it to use:
* `$MAX_REQUEST_SIZE`: The maximum size of POST requests that Dexter will process.
## License
Dexter is released under Version 3 of the GNU Affero General Public License (see `LICENSE`). The default font- JetBrainsMono from NerdFonts- is released under Version 1.1 of the SIL Open Font License (see `app/public/.assets/FONT-LICENSE`).
Dexter is released under Version 3 of the GNU Affero General Public License (see `LICENSE`). The default font- JetBrainsMono from NerdFonts- is released under Version 1.1 of the SIL Open Font License (see `app/public/.assets/FONT-LICENSE`).

67
app/dexter.pl Normal file → Executable file
View File

@ -3,7 +3,6 @@
use Module::Installed::Tiny qw(module_installed);
use Mojolicious::Lite -signatures;
use Mojo::Util qw(url_unescape);
use Readonly;
@ -33,7 +32,10 @@ Readonly::Hash my %MEANING_OF_HTTP_CODE => (
Readonly my $ROOT_DIRECTORY => 'public';
Readonly my $SOCKET_DIRECTORY => '/var/www/run';
Readonly my $MAX_REQUEST_SIZE => 100 * $MEGABYTE;
Readonly my $TEMP_DIRECTORY => '/tmp/dexter';
Readonly my $MAX_REQUEST_SIZE => $GIGABYTE;
mkdir $TEMP_DIRECTORY;
Readonly::Hash my %PERMISSIONS => (
NONE => 0,
@ -250,7 +252,7 @@ sub user_has_permission_on_path ($user, $permission, $path) {
my $permit = $rule_ref->[1];
my $permission = $PERMISSIONS{$permission};
next if not $path->to_string =~ m/$regex/;
next if not $path->to_route =~ m/$regex/;
return ( $permission & $permit ) == $permission;
}
@ -287,7 +289,6 @@ sub get_sorts_hash_from_query ($query_string) {
sub turn_string_into_path_using_url ($string, $url) {
my $path = $url->path->clone->merge($string);
$path = sanitize_path($path);
$path = unescape_path($path);
$path = $path->trailing_slash(0);
}
@ -315,7 +316,7 @@ sub user_save_file_to_path ($user, $file, $path) {
my ( $code, $message ) = check_user_can_create_file($user, $path);
return $code, $message if $code != 200;
my $path_string = $ROOT_DIRECTORY . $path->to_string;
my $path_string = $ROOT_DIRECTORY . $path->to_route;
$file->move_to($path_string)
or return 500, "Could not upload file '$path_string'!";
@ -326,7 +327,7 @@ sub user_mkdir_at_path ($user, $path) {
my ( $code, $message ) = check_user_can_create_file($user, $path);
return $code, $message if $code != 200;
my $path_string = $ROOT_DIRECTORY . $path->to_string;
my $path_string = $ROOT_DIRECTORY . $path->to_route;
mkdir($path_string)
or return 500, "Directory '$path_string' could not be created!";
@ -337,7 +338,7 @@ sub user_delete_path ($user, $path) {
my ( $code, $message ) = check_user_can_delete_file($user, $path);
return $code, $message if $code != 200;
my $path_string = $ROOT_DIRECTORY . $path->to_string;
my $path_string = $ROOT_DIRECTORY . $path->to_route;
my $err = 0;
if ( -d $path_string ) {
$err = not rmtree($path_string);
@ -360,8 +361,8 @@ sub user_move_path_to_path ($user, $path, $new_path) {
( $code, $message ) = check_user_can_create_file($user, $new_path);
return $code, $message if $code != 200;
my $path_string = $ROOT_DIRECTORY . $path->to_string;
my $new_path_string = $ROOT_DIRECTORY . $new_path->to_string;
my $path_string = $ROOT_DIRECTORY . $path->to_route;
my $new_path_string = $ROOT_DIRECTORY . $new_path->to_route;
move($path_string, $new_path_string)
or return 500,
"Could not move file '$path_string' to '$new_path_string'!";
@ -370,7 +371,7 @@ sub user_move_path_to_path ($user, $path, $new_path) {
}
sub get_files_at_path ($path) {
my $path_string = $path->to_string;
my $path_string = $path->to_route;
my $directory_path = $ROOT_DIRECTORY . $path_string;
opendir my $directory, $directory_path or return ();
@ -424,14 +425,6 @@ sub sort_symbol_for_order ($sort_order) {
}
}
sub unescape_path ($path) {
my $path_string = $path->to_string;
$path_string = url_unescape($path_string);
return Mojo::Path->new($path_string);
}
sub get_file_with_name ($name) {
my (
$device, $inode, $mode, $nlink, $uid, $gid, $rdev, $size, $atime,
@ -446,21 +439,21 @@ sub get_file_with_name ($name) {
}
my %file = (
name => $name,
device => $device,
inode => $inode,
mode => $mode,
nlink => $nlink,
uid => $uid,
gid => $gid,
rdev => $rdev,
size => $size,
atime => $atime,
mtime => $mtime,
ctime => $ctime,
blksize => $blksize,
blocks => $blocks,
type => $type,
name => $name,
device => $device,
inode => $inode,
mode => $mode,
nlink => $nlink,
uid => $uid,
gid => $gid,
rdev => $rdev,
size => $size,
atime => $atime,
mtime => $mtime,
ctime => $ctime,
blksize => $blksize,
blocks => $blocks,
type => $type,
);
return \%file;
@ -550,7 +543,7 @@ sub parse_sort_query ($query_string) {
}
sub check_user_can_create_file ($user, $path) {
my $path_string = $path->to_string;
my $path_string = $path->to_route;
if ( not user_has_permission_on_path($user, 'CREATE', $path) ) {
return 403, "You do not have permission to create '$path_string'!";
@ -560,7 +553,7 @@ sub check_user_can_create_file ($user, $path) {
return 409, "'$path_string' already exists!";
}
my $parent = $path->to_dir->to_string;
my $parent = $path->to_dir->to_route;
if ( not -e $ROOT_DIRECTORY . $parent ) {
return 409, "Parent directory '$parent' does not exist!";
@ -574,7 +567,7 @@ sub check_user_can_create_file ($user, $path) {
}
sub check_user_can_delete_file ($user, $path) {
my $path_string = $path->to_string;
my $path_string = $path->to_route;
if ( not user_has_permission_on_path($user, 'DELETE', $path) ) {
return 403, "You do not have permission to delete '$path_string'!";
@ -594,7 +587,7 @@ if ( module_installed('OpenBSD::Unveil') ) {
unveil($directory, 'r');
}
unveil($ENV{TMPDIR}, 'rw');
unveil($TEMP_DIRECTORY, 'rw');
unveil('/dev/null', 'rw');
my ( undef, $parent_directory, undef ) = File::Spec->splitpath($0);

View File

@ -68,4 +68,4 @@ function get_file_name_from_url(url) {
}
return name;
}
}

View File

@ -1,3 +1,2 @@
dexter_socket_path="/var/www/run/dexter.sock"
dexter_script_path="/var/www/cgi-bin/dexter/dexter.pl"
dexter_tmpdir="/tmp/dexter"
dexter_script_path="/var/www/cgi-bin/dexter/app/dexter.pl"

View File

@ -1,7 +1,7 @@
server "<INSERT_DOMAIN_HERE>" {
listen on egress tls port 443
connection max request body 1000000
connection max request body 1000000000
fastcgi socket "/run/dexter.sock"
@ -20,4 +20,4 @@ server "<INSERT_DOMAIN_HERE>" {
}
gzip-static
}
}

View File

@ -2,11 +2,9 @@
daemon="plackup"
daemon_user="www"
dexter_script_path="/var/www/cgi-bin/dexter/dexter.pl"
dexter_script_path="/var/www/cgi-bin/dexter/app/dexter.pl"
dexter_socket_path="/var/www/run/dexter.sock"
dexter_psgi_mode="production"
dexter_tmpdir="/tmp/dexter"
TMPDIR="$dexter_tmpdir"; export TMPDIR
. /etc/rc.d/rc.subr
@ -28,4 +26,4 @@ rc_configtest() {
rc_exec "/bin/ksh -n /etc/dexter.conf"
}
rc_cmd $1
rc_cmd $1