Compare commits
2 Commits
029a5c07e1
...
b8b7fc68bd
Author | SHA1 | Date |
---|---|---|
Sam Greytalon | b8b7fc68bd | |
Sam Greytalon | 251c7640a3 |
|
@ -4,6 +4,7 @@ Dexter is a Mojolicious webapp that handles the generation of index pages under
|
||||||
## Setup
|
## Setup
|
||||||
Dexter depends on these Perl modules:
|
Dexter depends on these Perl modules:
|
||||||
* Cwd
|
* Cwd
|
||||||
|
* Encode
|
||||||
* Readonly
|
* Readonly
|
||||||
* File::Path
|
* File::Path
|
||||||
* File::Spec
|
* File::Spec
|
||||||
|
@ -35,6 +36,7 @@ Dexter needs to know about two directories you want it to use:
|
||||||
|
|
||||||
### Other
|
### Other
|
||||||
* `$MAX_REQUEST_SIZE`: The maximum size of POST requests that Dexter will process.
|
* `$MAX_REQUEST_SIZE`: The maximum size of POST requests that Dexter will process.
|
||||||
|
* `$FS_ENCODING`: The character encoding that the underlying filesystem uses to store filenames. The default value of `UTF-8` is most likely correct.
|
||||||
|
|
||||||
## License
|
## 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`).
|
||||||
|
|
|
@ -4,6 +4,9 @@ use Module::Installed::Tiny qw(module_installed);
|
||||||
|
|
||||||
use Mojolicious::Lite -signatures;
|
use Mojolicious::Lite -signatures;
|
||||||
|
|
||||||
|
use Encode::Locale;
|
||||||
|
use Encode;
|
||||||
|
|
||||||
use Readonly;
|
use Readonly;
|
||||||
|
|
||||||
use Cwd;
|
use Cwd;
|
||||||
|
@ -34,6 +37,7 @@ Readonly::Hash my %MEANING_OF_HTTP_CODE => (
|
||||||
Readonly my $ROOT_DIRECTORY => 'public';
|
Readonly my $ROOT_DIRECTORY => 'public';
|
||||||
Readonly my $SOCKET_DIRECTORY => '/var/www/run';
|
Readonly my $SOCKET_DIRECTORY => '/var/www/run';
|
||||||
Readonly my $TEMP_DIRECTORY => '/tmp/dexter';
|
Readonly my $TEMP_DIRECTORY => '/tmp/dexter';
|
||||||
|
Readonly my $FS_ENCODING => 'UTF-8';
|
||||||
Readonly my $MAX_REQUEST_SIZE => $GIGABYTE;
|
Readonly my $MAX_REQUEST_SIZE => $GIGABYTE;
|
||||||
|
|
||||||
mkdir $TEMP_DIRECTORY;
|
mkdir $TEMP_DIRECTORY;
|
||||||
|
@ -339,7 +343,7 @@ sub make_size_human_readable ($size) {
|
||||||
|
|
||||||
sub user_save_file_to_path ($user, $file, $path) {
|
sub user_save_file_to_path ($user, $file, $path) {
|
||||||
my ( $code, $message ) = check_user_can_create_file($user, $path);
|
my ( $code, $message ) = check_user_can_create_file($user, $path);
|
||||||
( $code, $message ) = check_dexter_can_edit_file($path);
|
( $code, $message ) = check_dexter_can_create_file($path);
|
||||||
return $code, $message if $code != 200;
|
return $code, $message if $code != 200;
|
||||||
|
|
||||||
my $path_string = $ROOT_DIRECTORY . $path->to_route;
|
my $path_string = $ROOT_DIRECTORY . $path->to_route;
|
||||||
|
@ -351,7 +355,7 @@ sub user_save_file_to_path ($user, $file, $path) {
|
||||||
|
|
||||||
sub user_mkdir_at_path ($user, $path) {
|
sub user_mkdir_at_path ($user, $path) {
|
||||||
my ( $code, $message ) = check_user_can_create_file($user, $path);
|
my ( $code, $message ) = check_user_can_create_file($user, $path);
|
||||||
( $code, $message ) = check_dexter_can_edit_file($path);
|
( $code, $message ) = check_dexter_can_create_file($path);
|
||||||
return $code, $message if $code != 200;
|
return $code, $message if $code != 200;
|
||||||
|
|
||||||
my $path_string = $ROOT_DIRECTORY . $path->to_route;
|
my $path_string = $ROOT_DIRECTORY . $path->to_route;
|
||||||
|
@ -388,7 +392,7 @@ sub user_move_path_to_path ($user, $path, $new_path) {
|
||||||
return $code, $message if $code != 200;
|
return $code, $message if $code != 200;
|
||||||
|
|
||||||
( $code, $message ) = check_user_can_create_file($user, $new_path);
|
( $code, $message ) = check_user_can_create_file($user, $new_path);
|
||||||
( $code, $message ) = check_dexter_can_edit_file($new_path);
|
( $code, $message ) = check_dexter_can_create_file($new_path);
|
||||||
return $code, $message if $code != 200;
|
return $code, $message if $code != 200;
|
||||||
|
|
||||||
my $path_string = $ROOT_DIRECTORY . $path->to_route;
|
my $path_string = $ROOT_DIRECTORY . $path->to_route;
|
||||||
|
@ -469,21 +473,22 @@ sub get_file_with_name ($name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
my %file = (
|
my %file = (
|
||||||
name => $name,
|
name => $name,
|
||||||
device => $device,
|
name_dec => Encode::decode($FS_ENCODING, $name),
|
||||||
inode => $inode,
|
device => $device,
|
||||||
mode => $mode,
|
inode => $inode,
|
||||||
nlink => $nlink,
|
mode => $mode,
|
||||||
uid => $uid,
|
nlink => $nlink,
|
||||||
gid => $gid,
|
uid => $uid,
|
||||||
rdev => $rdev,
|
gid => $gid,
|
||||||
size => $size,
|
rdev => $rdev,
|
||||||
atime => $atime,
|
size => $size,
|
||||||
mtime => $mtime,
|
atime => $atime,
|
||||||
ctime => $ctime,
|
mtime => $mtime,
|
||||||
blksize => $blksize,
|
ctime => $ctime,
|
||||||
blocks => $blocks,
|
blksize => $blksize,
|
||||||
type => $type,
|
blocks => $blocks,
|
||||||
|
type => $type,
|
||||||
);
|
);
|
||||||
|
|
||||||
return \%file;
|
return \%file;
|
||||||
|
@ -620,6 +625,16 @@ sub check_dexter_can_edit_file ($path) {
|
||||||
return 200, '';
|
return 200, '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub check_dexter_can_create_file ($path) {
|
||||||
|
my $path_string = $path->clone->trailing_slash(0)->to_dir->to_route;
|
||||||
|
|
||||||
|
if ( not -w $ROOT_DIRECTORY . $path_string ) {
|
||||||
|
return 500, "Dexter cannot create the file at '$path_string'!";
|
||||||
|
}
|
||||||
|
|
||||||
|
return 200, '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( module_installed('OpenBSD::Unveil') ) {
|
if ( module_installed('OpenBSD::Unveil') ) {
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
<html lang="en_US">
|
<html lang="en_US">
|
||||||
<head>
|
<head>
|
||||||
<title>Index of <%= $c->req->url->path->to_string %></title>
|
<title>Index of <%= $c->req->url->path->to_route %></title>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="stylesheet" href="/.assets/style.css" />
|
<link rel="stylesheet" href="/.assets/style.css" />
|
||||||
<script src="/.assets/main.js"></script>
|
<script src="/.assets/main.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<h1>Index of <%= $c->req->url->path->to_string %></h1>
|
<h1>Index of <%= $c->req->url->path->to_route %></h1>
|
||||||
</header>
|
</header>
|
||||||
<article>
|
<article>
|
||||||
<table>
|
<table>
|
||||||
|
@ -64,8 +64,8 @@
|
||||||
% foreach my $file (@$FILES) {
|
% foreach my $file (@$FILES) {
|
||||||
<tr>
|
<tr>
|
||||||
<td class="left">
|
<td class="left">
|
||||||
<a href="<%= $file->{name} %>">
|
<a href="<%= $file->{name_dec} %>">
|
||||||
<%= $file->{name} %>
|
<%= $file->{name_dec} %>
|
||||||
</a>
|
</a>
|
||||||
<span class="buttons">
|
<span class="buttons">
|
||||||
% if ( permission_available_at_path('MOVE', $file->{name}) ) {
|
% if ( permission_available_at_path('MOVE', $file->{name}) ) {
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
<a class="button" onclick="file_move(this)"> ✎ </a>
|
<a class="button" onclick="file_move(this)"> ✎ </a>
|
||||||
<form action="./" method="post">
|
<form action="./" method="post">
|
||||||
<input type="hidden" name="intent" value="move" />
|
<input type="hidden" name="intent" value="move" />
|
||||||
<input type="hidden" name="target_path" value="<%= $file->{name} %>" />
|
<input type="hidden" name="target_path" value="<%= $file->{name_dec} %>" />
|
||||||
<input type="hidden" name="dest_path" value="" />
|
<input type="hidden" name="dest_path" value="" />
|
||||||
</form>
|
</form>
|
||||||
</span>
|
</span>
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
<a class="button" onclick="file_delete(this)"> ✖ </a>
|
<a class="button" onclick="file_delete(this)"> ✖ </a>
|
||||||
<form action="./" method="post">
|
<form action="./" method="post">
|
||||||
<input type="hidden" name="intent" value="delete" />
|
<input type="hidden" name="intent" value="delete" />
|
||||||
<input type="hidden" name="target_path" value="<%= $file->{name} %>" />
|
<input type="hidden" name="target_path" value="<%= $file->{name_dec} %>" />
|
||||||
</form>
|
</form>
|
||||||
</span>
|
</span>
|
||||||
% }
|
% }
|
||||||
|
|
Loading…
Reference in New Issue