From f276084429f7fee87765e97d313af98d0dc9bbc6 Mon Sep 17 00:00:00 2001
From: Clifton Palmer
Date: Sat, 19 Aug 2023 07:40:39 -0500
Subject: [PATCH] Replaced old perl publish with web-accessible publish - basic
auth for all web interfaces now at /lua/ - external docker httpd password
directory for security (needs initialization) - html form for submitting
publishing patterns
---
.env | 2 -
.gitignore | 1 +
Dockerfile | 5 ++-
docker-compose.yml | 8 ++--
httpd.conf | 20 +++++++++-
lua/dump_files.lua | 42 ++++++++++++++++++++
lua/publish.lua | 38 ++++++++++++++++++
lua/publish.sh | 22 +++++++++++
lua/submit.html | 24 ++++++++++++
public | 98 ----------------------------------------------
public.sh | 10 -----
readme.md | 18 ++-------
12 files changed, 158 insertions(+), 130 deletions(-)
delete mode 100644 .env
create mode 100644 lua/dump_files.lua
create mode 100644 lua/publish.lua
create mode 100755 lua/publish.sh
create mode 100644 lua/submit.html
delete mode 100755 public
delete mode 100755 public.sh
diff --git a/.env b/.env
deleted file mode 100644
index f9b18d8..0000000
--- a/.env
+++ /dev/null
@@ -1,2 +0,0 @@
-LOCAL_STORAGE=/mnt/data2/purplebirdman/art
-IPV4_WAN=public.purplebirdman.com
diff --git a/.gitignore b/.gitignore
index 1377554..cba83f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
+.env
*.swp
diff --git a/Dockerfile b/Dockerfile
index 0624f65..8659635 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,7 @@
FROM httpd:2.4-alpine
+# open htdocs so scripts can write dynamically into there
+RUN chmod 777 /usr/local/apache2/htdocs
+
COPY /httpd.conf /usr/local/apache2/conf/httpd.conf
-COPY /public /root/public
+COPY /lua /usr/local/apache2/lua
diff --git a/docker-compose.yml b/docker-compose.yml
index 4fc3c44..e0ed0d7 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,16 +2,18 @@ version: '3'
services:
web:
build: .
- image: cjpalmer/public:1.1.0
+ image: cjpalmer/public:1.2.0
volumes:
- - ${LOCAL_STORAGE}:/storage
+ - ${SHARE_ROOT}:/storage
- public_data:/usr/local/apache2/htdocs
+ - httpd_users:/usr/local/apache2/auth
environment:
- PUBLIC_ROOT_DIR=/storage
- PUBLIC_LINK_DIR=/usr/local/apache2/htdocs
- - PUBLIC_HTTP_URI=https://${IPV4_WAN}
ports:
- 80:80
volumes:
public_data:
driver: local
+ httpd_users:
+ driver: local
diff --git a/httpd.conf b/httpd.conf
index d7ce626..e2bb8fb 100644
--- a/httpd.conf
+++ b/httpd.conf
@@ -127,7 +127,7 @@ LoadModule log_config_module modules/mod_log_config.so
#LoadModule log_debug_module modules/mod_log_debug.so
#LoadModule log_forensic_module modules/mod_log_forensic.so
#LoadModule logio_module modules/mod_logio.so
-#LoadModule lua_module modules/mod_lua.so
+LoadModule lua_module modules/mod_lua.so
LoadModule env_module modules/mod_env.so
#LoadModule mime_magic_module modules/mod_mime_magic.so
#LoadModule cern_meta_module modules/mod_cern_meta.so
@@ -229,7 +229,7 @@ Group daemon
# e-mailed. This address appears on some server-generated pages, such
# as error documents. e.g. admin@your-domain.com
#
-ServerAdmin purplebirdman@mail.purplebirdman.online
+ServerAdmin purplebirdman@purplebirdman.com
#
# ServerName gives the name and port that the server uses to identify itself.
@@ -307,6 +307,11 @@ DocumentRoot "/usr/local/apache2/htdocs"
Require all denied
+# run lua scripts using ".lua" extension
+
+ SetHandler lua-script
+
+
#
# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a
@@ -380,6 +385,7 @@ LogLevel warn
# directives as to Alias.
#
ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/"
+ ScriptAlias /lua/ "/usr/local/apache2/lua/"
@@ -401,6 +407,16 @@ LogLevel warn
Require all granted
+# more lua stuff
+
+ AuthType Basic
+ AuthName "Restricted Files"
+ AuthUserFile "/usr/local/apache2/auth/passwords"
+ AllowOverride None
+ Options None
+ Require valid-user
+
+
#
# Avoid passing HTTP_PROXY environment to CGI's on this or any proxied
diff --git a/lua/dump_files.lua b/lua/dump_files.lua
new file mode 100644
index 0000000..4f98bcb
--- /dev/null
+++ b/lua/dump_files.lua
@@ -0,0 +1,42 @@
+require "apache2"
+
+--[[
+ Dumps all the published links
+--]]
+function dump_files(t, r, dir)
+ for _, f in ipairs(r:get_direntries(dir)) do
+ if f ~= "." and f ~= ".." then
+ local filepath = dir .. "/" .. f
+ local info = r:stat(filepath)
+ if info then
+ -- if this is a file, then add it to the table!
+ if info.filetype == 1 then
+ t[filepath] = info
+ end
+
+ -- if this is a dir, then descend into it
+ if info.filetype == 2 then
+ dump_files(t, r, filepath)
+ end
+ end
+ end
+ end
+end
+
+function handle(r)
+ r.content_type = "text/plain"
+
+ if r.method == 'GET' then
+ local links = {}
+ dump_files(links, r, r.document_root)
+
+ for filepath, info in pairs(links) do
+ r:puts( ("%s\n"):format(
+ filepath:gsub(r.document_root, r.server_name .. ":" ..r.port)
+ ))
+ end
+ else
+ return 501
+ end
+ return apache2.OK
+end
diff --git a/lua/publish.lua b/lua/publish.lua
new file mode 100644
index 0000000..5fa18c0
--- /dev/null
+++ b/lua/publish.lua
@@ -0,0 +1,38 @@
+require "apache2"
+
+function publish(dir, pattern)
+ local cmd = ("%s/publish.sh %s"):format(dir, pattern)
+ local handle = io.popen(cmd)
+ local output = handle:read('*a')
+ handle:close()
+
+ return output
+end
+
+function get_form(dir)
+ local handle = io.open(dir .. '/submit.html')
+ local output = handle:read('*a')
+ handle:close()
+
+ return output;
+end
+
+function handle(r)
+ r.content_type = "text/html"
+
+ local args = r:parseargs()
+ local pattern = args.pattern
+
+ if pattern then
+ local nonce = publish(r.context_document_root, pattern)
+ local uri = ("%s://%s:%s/%s"):format(
+ r.is_https and "https" or "http",
+ r.server_name, r.port, nonce)
+ r:puts( ([[%s]]):format(uri, uri) )
+ else
+ local template = get_form(r.context_document_root)
+ r:puts( template )
+ end
+
+ return apache2.OK
+end
diff --git a/lua/publish.sh b/lua/publish.sh
new file mode 100755
index 0000000..bf88fbd
--- /dev/null
+++ b/lua/publish.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# make sure public root and link dirs are declared
+[[ -z "$PUBLIC_ROOT_DIR" ]] && echo Expected PUBLIC_ROOT_DIR && exit 1
+[[ -z "$PUBLIC_LINK_DIR" ]] && echo Expected PUBLIC_LINK_DIR && exit 1
+
+[[ -z "$1" ]] && echo Expected pattern && exit 1
+
+# if pattern matches files from storage,
+# create nonce directory
+# create symlinks to matching files
+nonce=$(head /dev/urandom | sha1sum -b | awk '{print $1}')
+symlink_dir=$PUBLIC_LINK_DIR/$nonce
+
+find $PUBLIC_ROOT_DIR -type f -name "*$1*" | while read fname
+do
+ [[ -d $symlink_dir ]] || mkdir -p $symlink_dir
+ ln -s $fname $symlink_dir/$(echo $fname | sed 's|^.*/||')
+done
+
+# print nonce directory
+echo $nonce
diff --git a/lua/submit.html b/lua/submit.html
new file mode 100644
index 0000000..18314c9
--- /dev/null
+++ b/lua/submit.html
@@ -0,0 +1,24 @@
+
+
+Public
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public b/public
deleted file mode 100755
index 2dd2481..0000000
--- a/public
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-
-use File::Spec;
-use File::Path qw/ make_path /;
-
-my $root_dir = $ENV{PUBLIC_ROOT_DIR}
- or die "Need PUBLIC_ROOT_DIR\n";
-my $link_dir = $ENV{PUBLIC_LINK_DIR}
- or die "Need PUBLIC_LINK_DIR\n";
-my $http_uri = $ENV{PUBLIC_HTTP_URI}
- or die "Need PUBLIC_HTTP_URI\n";
-
-
-sub nonce {
- my $n = shift;
- $n = 10 unless $n > 0;
-
- my @chars = ( 'a' .. 'z', 'A' .. 'Z', '0' .. '9' );
- my @path = ();
- push @path, $chars[ rand @chars ] for 1 .. $n;
-
- return join '', @path;
-}
-
-sub makeNonceDir {
- my $nonce = shift;
- my $path = File::Spec->catdir($link_dir, $nonce);
- make_path($path, { chmod => 0777 });
- return $path, ;
-}
-
-sub addFiles {
- # get list of files matching name from root directory
- my $name = shift
- or die "Need filename!\n";
-
- opendir DIR, $root_dir
- or die $!;
- my @files = grep /$name/i, readdir(DIR);
- closedir DIR;
-
- # exit if no files found
- die "No match: $name\n" unless @files;
-
- # create nonce dir and add symbolic links
- my $nonce = nonce(20);
- my $nonce_dir = makeNonceDir($nonce);
-
- for my $file (@files) {
- my $root_filepath = File::Spec->catfile($root_dir, $file);
- my $link_filepath = File::Spec->catfile($nonce_dir, $file);
-
- symlink $root_filepath, $link_filepath
- or die "Unable to create symlink: $root_filepath -> $link_filepath";
-
- my $uri_link = join '/', $http_uri, $nonce, $file;
- print "$uri_link\n";
- }
-}
-
-sub listFiles {
- opendir DIR, $link_dir;
- my @nonces = readdir(DIR);
- closedir DIR;
-
- for my $nonce (@nonces) {
- next if $nonce eq '.';
- next if $nonce eq '..';
-
- # ensure it's a directory
- my $nonce_dir = File::Spec->catdir($link_dir, $nonce);
- next unless -d $nonce_dir;
-
- # make URIs for all the files in the nonce dirs
- opendir DIR, $nonce_dir;
- my @files = readdir(DIR);
- closedir DIR;
-
- for my $file (@files) {
- next if $file eq '.';
- next if $file eq '..';
-
- my $uri_link = join '/', $http_uri, $nonce, $file;
- print "$uri_link\n";
- }
- }
-}
-
-
-# script begins
-if (@ARGV) {
- addFiles($_) for @ARGV;
-}
-else {
- listFiles;
-}
diff --git a/public.sh b/public.sh
deleted file mode 100755
index 6ed9695..0000000
--- a/public.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-service=proxy_public
-
-for f in $(docker service ps -q $service)
-do
- [[ running == $(docker inspect --format '{{.Status.State}}' $f) ]] || continue
- container_id=$(docker inspect --format '{{.Status.ContainerStatus.ContainerID}}' $f)
- echo docker exec $container_id /root/public "$@"
- docker exec $container_id /root/public "$@"
-done
diff --git a/readme.md b/readme.md
index 27b668b..f8fb6dc 100644
--- a/readme.md
+++ b/readme.md
@@ -7,22 +7,12 @@ A stupid and easy way to publicize my stuff. like dropbox but safer.
docker stack deploy -c <(docker-compose config) public
```
-### creating a public directory by filename regex
-```
-cliftonpalmer@pop-os:~/swarm/share-public$ ./public.sh simplify
-http://public.purplebirdman.online/1ojxVHOXk9u89u234erso7df/SimplifyPikoPseftis3.jpg
-http://public.purplebirdman.online/1ojxVHOXk9u89u234erso7df/SimplifyPikoPseftis.png
-http://public.purplebirdman.online/1ojxVHOXk9u89u234erso7df/SimplifyPikoPseftis.clip
-http://public.purplebirdman.online/1ojxVHOXk9u89u234erso7df/SimplifyPikoPseftis2.png
-```
+### reaching the services
+
+Must authorize self through ```$hostname```/lua/publish.lua and set up valid users on first deployment
-### listing public directories and contents
```
-cliftonpalmer@pop-os:~/swarm/share-public$ ./public.sh
-http://public.purplebirdman.online/1ojxVHOXk9u89u234erso7df/SimplifyPikoPseftis3.jpg
-http://public.purplebirdman.online/1ojxVHOXk9u89u234erso7df/SimplifyPikoPseftis2.png
-http://public.purplebirdman.online/1ojxVHOXk9u89u234erso7df/SimplifyPikoPseftis.png
-http://public.purplebirdman.online/1ojxVHOXk9u89u234erso7df/SimplifyPikoPseftis.clip
+htpasswd -c passwords $username
```
## todo
--
2.47.2