Compare commits
4 Commits
a7e848d4a1
...
2926fd52cd
Author | SHA1 | Date |
---|---|---|
Sam Greytalon | 2926fd52cd | |
Sam Greytalon | dfc2c7ea2e | |
Sam Greytalon | d88cb236c7 | |
Sam Greytalon | a4f1f18cb4 |
|
@ -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`).
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -68,4 +68,4 @@ function get_file_name_from_url(url) {
|
|||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue