aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md10
-rw-r--r--extra/Makefile128
-rw-r--r--extra/pip-helper.sh32
-rw-r--r--extra/stackbin.conf.apache62
-rw-r--r--extra/stackbin.conf.nginx13
-rwxr-xr-xextra/stackbin.init172
-rw-r--r--extra/stackbin.service20
-rw-r--r--extra/stackbin.spec171
-rw-r--r--extra/stackbin.sysusers3
-rwxr-xr-xstackbin.py9
-rw-r--r--stackbin.wsgi.ini4
11 files changed, 621 insertions, 3 deletions
diff --git a/README.md b/README.md
index 8e5cc6b..cdae7f2 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,7 @@ This is my proposed solution to my pastebin problem.
* "Reply to" pastes to make parent/children relationships
* UUIDs instead of sequential integer ID numbers
* Private pastes (accessible to admin, and to users with the whole link)
+* Reverse-proxy autoconfiguration by visiting /set
# Using stackbin
## Installing
@@ -37,6 +38,14 @@ Run the server in a full wsgi environment for the cleanup timer to operate.
./stackbin.bin
+If you use stackbin behind a reverse-proxy such as nginx with example file `stackbin.conf.nginx`, then you can have it autodetect the correct top-level path by visiting path:
+
+ /set
+
+This means that if your app is behind `http://example.com/stackbin/` then you would just visit once page:
+
+ http://example.com/stackbin/set
+
# Improvements
I still need to work on these tasks:
@@ -46,7 +55,6 @@ I still need to work on these tasks:
## Release
-* Document centos7 dependencies
* Deploy to prod
# Alternatives
diff --git a/extra/Makefile b/extra/Makefile
new file mode 100644
index 0000000..f707480
--- /dev/null
+++ b/extra/Makefile
@@ -0,0 +1,128 @@
+# File: Makefile for stackbin
+# Location: stackbin source package
+# Author: bgstack15
+# Startdate: 2020-12-30
+# Title: Makefile for stackbin source package
+# Purpose: To use traditional Unix make utility
+# History:
+# Usage:
+# Reference:
+# hex-zero Makefile
+# Improve:
+# add man page?
+# Document:
+# Dependencies:
+# build-devuan:
+
+APPNAME = stackbin
+APPVERSION = 0.0.1
+SRCDIR = $(CURDIR)/..# because Makefile is in extra/ inside this repo
+prefix = /usr
+SYSCONFDIR = $(DESTDIR)/etc
+DEFAULTDIR = $(DESTDIR)/etc/sysconfig# for debian use '$(DESTDIR)/etc/default'
+LIBEXECDIR = $(DESTDIR)$(prefix)/libexec
+SHAREDIR = $(DESTDIR)$(prefix)/share
+DOCDIR = $(SHAREDIR)/doc/$(APPNAME)
+APPDIR = $(SHAREDIR)/$(APPNAME)
+APPVARDIR = $(DESTDIR)/var/www/$(APPNAME)
+MANDIR = $(SHAREDIR)/man
+SYSVDIR = $(SYSCONFDIR)/init.d
+SYSDDIR = $(DESTDIR)$(prefix)/lib/systemd/system
+LOGDIR = $(DESTDIR)/var/log/stackbin
+APACHEDIR = $(SYSCONFDIR)/httpd/conf.d# for debian use '$(SYSCONFDIR)/apache2/sites-available'
+CRONDIR = $(SYSCONFDIR)/cron.d
+SBINDIR = $(DESTDIR)$(prefix)/sbin
+
+# variables for deplist
+DEPTYPE = dep
+SEPARATOR = ,
+
+awkbin :=$(shell which awk)
+chmodbin :=$(shell which chmod)
+cpbin :=$(shell which cp)
+echobin :=$(shell which echo)
+falsebin :=$(shell which false)
+findbin :=$(shell which find)
+grepbin :=$(shell which grep)
+gzipbin :=$(shell which gzip)
+installbin :=$(shell which install)
+rmbin :=$(shell which rm)
+rmdirbin :=$(shell which rmdir)
+sedbin :=$(shell which sed)
+sortbin :=$(shell which sort)
+truebin :=$(shell which true)
+uniqbin :=$(shell which uniq)
+xargsbin :=$(shell which xargs)
+
+with_apache ?= YES
+with_init ?= YES
+with_systemd ?= NO
+with_pip_helper ?= NO
+
+all:
+ -@echo "Nothing to build." && ${truebin}
+
+install: install_files
+
+.PHONY: clean install install_files uninstall list deplist deplist_opts
+
+list:
+ @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | ${awkbin} -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | ${sortbin} | ${grepbin} -E -v -e '^[^[:alnum:]]' -e '^$@$$'
+
+deplist:
+ @# deplist 2020-04-18 input must be comma separated
+ @# DEPTYPE( dep , rec , sug ) for depends, recommends, or suggests
+ @if test -z "${DISTRO}" ; then ${echobin} "Please run \`make deplist\` with DISTRO= one of: `make deplist_opts 2>&1 1>/dev/null | ${xargsbin}`. Aborted." 1>&2 ; exit 1 ; fi
+ @if ! ${echobin} "${DEPTYPE}" | grep -qE "^(dep|rec|sug)$$" ; then ${echobin} "Please run \`make deplist\` with DEPTYPE= one of: dep, rec, sug. Undefined will use \`dep\`. Aborted." 1>&2 ; exit 1; fi
+ @${grepbin} -h --exclude-dir='doc' -riIE "\<${DEPTYPE}-" ${SRCDIR} | ${awkbin} -v "domain=${DISTRO}" -v "deptype=${DEPTYPE}" 'tolower($$2) ~ deptype"-"domain {$$1="";$$2="";print}' | tr ',' '\n' | ${sortbin} | ${uniqbin} | ${sedbin} -r -e 's/^\s*//' -e "s/\s*\$$/${SEPARATOR}/" | ${xargsbin}
+
+deplist_opts:
+ @# deplist_opts 2020-04-18 find all available dependency domains
+ @${grepbin} -h -o -riIE '\<(dep|rec|sug)-[^\ :]+:' ${SRCDIR} | ${sedbin} -r -e 's/(dep|rec|sug)-//;' -e 's/:$$//;' | ${sortbin} | ${uniqbin} 1>&2
+
+install_files:
+ ${installbin} -m0755 -d ${LOGDIR} ${APPVARDIR}/upload ${APPDIR}/static ${APPDIR}/templates \
+ ${DOCDIR} ${SBINDIR} ${SYSCONFDIR} ${LIBEXECDIR}/${APPNAME}
+ ${installbin} -m0755 -t ${SBINDIR} ${SRCDIR}/${APPNAME}.bin
+ ${installbin} -m0644 -t ${LIBEXECDIR}/${APPNAME} ${SRCDIR}/${APPNAME}.py
+ ${installbin} -m0644 ${SRCDIR}/${APPNAME}.conf.example ${SYSCONFDIR}/${APPNAME}.conf
+ ${installbin} -m0644 ${SRCDIR}/${APPNAME}.wsgi.ini.example ${SYSCONFDIR}/${APPNAME}.wsgi.ini
+ ${installbin} -m0644 -t ${DOCDIR} ${SRCDIR}/*.md
+ ${installbin} -m0644 -t ${APPDIR}/static ${SRCDIR}/static/*
+ ${installbin} -m0644 -t ${APPDIR}/templates ${SRCDIR}/templates/*
+ifeq ($(with_apache),YES)
+ ${installbin} -m0755 -d ${APACHEDIR}
+ ${installbin} -m0644 ${SRCDIR}/extra/${APPNAME}.conf.apache ${APACHEDIR}/${APPNAME}.conf
+endif
+ifeq ($(with_init),YES)
+ ${installbin} -m0755 -d ${SYSVDIR}
+ ${installbin} -m0755 ${SRCDIR}/extra/${APPNAME}.init ${SYSVDIR}/${APPNAME}
+endif
+ifeq ($(with_systemd),YES)
+ ${installbin} -m0755 -d ${SYSDDIR}
+ ${installbin} -m0644 ${SRCDIR}/extra/stackbin.service -t ${SYSDDIR}
+endif
+ifeq ($(with_pip_helper),YES)
+ ${installbin} -m0755 -t ${LIBEXECDIR}/${APPNAME}/ ${SRCDIR}/extra/pip-helper.sh
+endif
+
+uninstall:
+ @${echobin} SRCDIR=${SRCDIR}
+ ${rmbin} -f ${APPDIR}/${APPNAME}.* \
+ ${DOCDIR}/* \
+ ${APPDIR}/static/* \
+ ${APPDIR}/templates/* \
+ ${LIBEXECDIR}/${APPNAME}/* \
+ ${SBINDIR}/${APPNAME}.bin \
+ 1>/dev/null 2>&1 || :
+ ${rmbin} -f ${APACHEDIR}/${APPNAME}.conf || :
+ ${rmbin} -f ${SYSVDIR}/${APPNAME} || :
+
+ # remove all installed directories that are now blank.
+ ${rmdirbin} ${APPVARDIR}/upload ${APPDIR}/static \
+ ${SYSVDIR} ${APACHEDIR} ${DOCDIR} \
+ ${LIBEXECDIR}/${APPNAME} ${LOGDIR} 2>/dev/null || :
+ ${rmdirbin} ${APPDIR} 2>/dev/null || :
+
+clean:
+ -@${echobin} "target $@ not implemented yet! Gotta say unh." && ${falsebin}
diff --git a/extra/pip-helper.sh b/extra/pip-helper.sh
new file mode 100644
index 0000000..499ef3b
--- /dev/null
+++ b/extra/pip-helper.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+# This file is part of the stackbin package.
+# It is designed to be run as root, and it will run the requisite pip commands for the discovered environment.
+
+contents="$( awk -F'=' '/ID=|VERSION_ID/{print $2}' /etc/os-release 2>/dev/null | sed -r -e 's/"//g;' )"
+id="$( echo "${contents}" | sed -n -e '1p' )"
+version_id="$( echo "${contents}" | sed -n -e '2p' )"
+
+echo "Any parameters sent to this script ${0} will be added to the list of packages to install."
+echo "This is particularly useful for adding the PyGObject for icon support on EL7."
+piplist="${1}"
+
+if echo "${id}" | grep -qiE 'rhel|centos' ;
+then
+ if echo "${version_id}" | grep -qiE '7' ;
+ then
+ piplist="${piplist} flask-sqlalchemy pytimeparse"
+ fi
+else
+ echo "Unknown os from /etc/os-release. Please investigate what pip3" 1>&2
+ echo "packages are required for this OS release and share it with upstream." 1>&2
+ echo "Aborted." 1>&2
+ exit 1
+fi
+
+if test -n "${piplist}" ;
+then
+ echo "Will try to serially install with pip these packages: ${piplist}"
+ for word in ${piplist} ; do
+ su stackbin -s /bin/sh -c "pip3 install --user ${word}" || exit 1
+ done
+fi
diff --git a/extra/stackbin.conf.apache b/extra/stackbin.conf.apache
new file mode 100644
index 0000000..fabcb21
--- /dev/null
+++ b/extra/stackbin.conf.apache
@@ -0,0 +1,62 @@
+# Apache example config for stackbin application
+# Needs setsebool -P http_can_network_connect 1
+# vim:set syntax=apache ts=3 sw=3 sts=3 sr et:
+<VirtualHost *:80>
+
+ ServerName d2-03a.ipa.example.com
+
+ ServerAdmin webmaster@localhost
+ DocumentRoot /var/www/html
+
+ #LogLevel info ssl:warn
+
+ ErrorLog ${APACHE_LOG_DIR}/error.log
+ CustomLog ${APACHE_LOG_DIR}/access.log combined
+
+ # OPTION 1: send to https
+ # force https for this path
+ RewriteEngine On
+ RewriteCond %{HTTPS} !=on
+ RewriteCond %{HTTP_HOST} !^(localhost|127.0.0.1)
+ RewriteRule ^/stackbin(.*) https://%{SERVER_NAME}/stackbin$1 [R,L]
+
+ # OPTION 2: Just use unencrypted
+ #ProxyPass /stackbin http://localhost:4680/
+ #ProxyPassReverse /stackbin http://localhost:4680/
+ #<Location /stackbin>
+ # RequestHeader append X-Forwarded-Prefix "/stackbin"
+ # RequestHeader set X-Forwarded-Proto "http"
+ #</Location>
+
+</VirtualHost>
+
+# To use OPTION 2 above, just disable this whole 443 virtualhost.
+<VirtualHost *:443>
+ ServerName d2-03a.ipa.example.com
+
+ ServerAdmin webmaster@localhost
+ DocumentRoot /var/www/html
+
+ #LogLevel info ssl:warn
+
+ ErrorLog ${APACHE_LOG_DIR}/ssl-error.log
+ CustomLog ${APACHE_LOG_DIR}/ssl-access.log combined
+
+ SSLEngine on
+ SSLProtocol all -SSLv2 -SSLv3
+ SSLHonorCipherOrder on
+ SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"
+
+ SSLCertificateFile /etc/ssl/private/https-d2-03a.ipa.example.com.pem
+ SSLCertificateKeyFile /etc/ssl/private/https-d2-03a.ipa.example.com-nopw.key
+
+ ProxyPass /stackbin http://localhost:4680/
+ ProxyPassReverse /stackbin http://localhost:4680/
+ <Location /stackbin>
+ # a2enmod headers. These are extra ones that are not provided by Apache natively.
+ RequestHeader set X-Forwarded-Proto "https"
+ # This header is not required to be set manually. The ProxyPass orand Location directive already provide it!
+ #RequestHeader append X-Forwarded-Prefix "/stackbin"
+ </Location>
+
+</VirtualHost>
diff --git a/extra/stackbin.conf.nginx b/extra/stackbin.conf.nginx
new file mode 100644
index 0000000..e53b252
--- /dev/null
+++ b/extra/stackbin.conf.nginx
@@ -0,0 +1,13 @@
+# Nginx example config for stackbin application
+# Needs setsebool -P http_can_network_connect 1
+location /stackbin/ {
+ #proxy_redirect off;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Script-Name /stackbin;
+ proxy_set_header X-Forwarded-Host $host;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-Prefix "/stackbin";
+ proxy_pass http://localhost:4680/;
+}
+
diff --git a/extra/stackbin.init b/extra/stackbin.init
new file mode 100755
index 0000000..232bca9
--- /dev/null
+++ b/extra/stackbin.init
@@ -0,0 +1,172 @@
+#!/bin/sh
+### BEGIN INIT INFO
+# Provides: stackbin
+# Required-Start: $local_fs $network $remote_fs $syslog
+# Required-Stop: $local_fs $network $remote_fs $syslog
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: File Upoad and Storage Service
+# Description: Python3 Flask application that presents a basic file hosting service
+### END INIT INFO
+
+# Author: B. Stack <bgstack15@gmail.com>
+
+# Do NOT "set -e"
+
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
+DAEMON_ARGS=""
+DAEMON=/usr/sbin/stackbin.bin
+DESC="stackbin"
+NAME=stackbin
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
+PIDFILE2=/var/www/stackbin/stackbin.pid
+PIDFILE=/var/run/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+USER=stackbin
+WSGIBIN=uwsgi_python39
+
+# Exit if the package is not installed
+[ -x "$DAEMON" ] || exit 0
+
+# Read configuration variable file if it is present
+[ -r /etc/default/$NAME ] && . /etc/default/$NAME
+
+# Load the VERBOSE setting and other rcS variables
+. /lib/init/vars.sh
+
+# Define LSB log_* functions.
+# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
+# and status_of_proc is working.
+. /lib/lsb/init-functions
+
+#
+# Function that starts the daemon/service
+#
+do_start()
+{
+ # Return
+ # 0 if daemon has been started
+ # 1 if daemon was already running
+ # 2 if daemon could not be started
+ #start-stop-daemon --start --quiet --chuid $USER --group $USER --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
+ # || return 1
+ #start-stop-daemon --start --quiet --chuid $USER --group $USER --background --pidfile $PIDFILE --exec $DAEMON -- \
+ # $DAEMON_ARGS \
+ # || return 2
+ #su $USER -c "$DAEMON" &
+ # The above code will not work for interpreted scripts, use the next
+ # six lines below instead (Ref: #643337, start-stop-daemon(8) )
+ start-stop-daemon --start --make-pidfile --pidfile $PIDFILE \
+ --chuid $USER --group $USER \
+ --startas $DAEMON \
+ --name $WSGIBIN --test > /dev/null \
+ || return 1
+ start-stop-daemon --start --background --make-pidfile --pidfile $PIDFILE --startas $DAEMON \
+ --chuid $USER --group $USER \
+ --name $WSGIBIN -- $DAEMON_ARGS \
+ || return 2
+
+ # Add code here, if necessary, that waits for the process to be ready
+ # to handle requests from services started subsequently which depend
+ # on this one. As a last resort, sleep for some time.
+}
+
+#
+# Function that stops the daemon/service
+#
+do_stop()
+{
+ # Return
+ # 0 if daemon has been stopped
+ # 1 if daemon was already stopped
+ # 2 if daemon could not be stopped
+ # other if a failure occurred
+ #start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --user $USER --pidfile $PIDFILE
+ /usr/bin/$WSGIBIN --stop $PIDFILE2 2>/dev/null
+ RETVAL="$?"
+ [ "$RETVAL" = 2 ] && return 2
+ # Wait for children to finish too if this is a daemon that forks
+ # and if the daemon is only ever run from this initscript.
+ # If the above conditions are not satisfied then add some other code
+ # that waits for the process to drop all resources that could be
+ # needed by services started subsequently. A last resort is to
+ # sleep for some time.
+ start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --user $USER --pidfile $PIDFILE
+ [ "$?" = 2 ] && return 2
+ # Many daemons don't delete their pidfiles when they exit.
+ rm -f $PIDFILE
+ return "$RETVAL"
+}
+
+#
+# Function that sends a SIGHUP to the daemon/service
+#
+do_reload() {
+ #
+ # If the daemon can reload its configuration without
+ # restarting (for example, when it is sent a SIGHUP),
+ # then implement that here.
+ #
+ start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $WSGIBIN
+ return 0
+}
+
+case "$1" in
+ start)
+ [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
+ do_start
+ case "$?" in
+ 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+ 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+ esac
+ ;;
+ stop)
+ [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
+ do_stop
+ case "$?" in
+ 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+ 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+ esac
+ ;;
+ status)
+ status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $?
+ ;;
+ #reload|force-reload)
+ #
+ # If do_reload() is not implemented then leave this commented out
+ # and leave 'force-reload' as an alias for 'restart'.
+ #
+ #log_daemon_msg "Reloading $DESC" "$NAME"
+ #do_reload
+ #log_end_msg $?
+ #;;
+ restart|force-reload)
+ #
+ # If the "reload" option is implemented then remove the
+ # 'force-reload' alias
+ #
+ log_daemon_msg "Restarting $DESC" "$NAME"
+ do_stop
+ case "$?" in
+ 0|1)
+ do_start
+ case "$?" in
+ 0) log_end_msg 0 ;;
+ 1) log_end_msg 1 ;; # Old process is still running
+ *) log_end_msg 1 ;; # Failed to start
+ esac
+ ;;
+ *)
+ # Failed to stop
+ log_end_msg 1
+ ;;
+ esac
+ ;;
+ *)
+ #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
+ echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
+ exit 3
+ ;;
+esac
+
+:
diff --git a/extra/stackbin.service b/extra/stackbin.service
new file mode 100644
index 0000000..f3088be
--- /dev/null
+++ b/extra/stackbin.service
@@ -0,0 +1,20 @@
+[Unit]
+Description=Stackbin pastebin service
+Wants=network-online.target
+After=network.target syslog.target
+
+[Service]
+#Environment=
+WorkingDirectory=/var/www/stackbin
+User=stackbin
+Group=stackbin
+Type=simple
+ExecStart=/usr/sbin/stackbin.bin
+TimeoutStartSec=120
+ExecStop=/usr/sbin/uwsgi --stop /var/www/stackbin/stackbin.pid
+RestartSec=15
+Restart=always
+KillSignal=SIGINT
+
+[Install]
+WantedBy=multi-user.target
diff --git a/extra/stackbin.spec b/extra/stackbin.spec
new file mode 100644
index 0000000..fcc9f8f
--- /dev/null
+++ b/extra/stackbin.spec
@@ -0,0 +1,171 @@
+# File: fuss.spec
+# Location: fuss package
+# Author: bgstack15
+# SPDX-License-Identifier: CC-BY-SA-4.0
+# Startdate: 2021-01-05
+# Title: Rpm spec for fuss package
+# Purpose: Provide build instructions for CentOS rpm for package
+# History:
+# Usage:
+# Reference:
+# Improve:
+# Documentation:
+# Dependencies:
+
+# Tunables
+# If you set with_icons to 1, then you will pull in a large amount of dependencies!
+%global with_icons 0
+# If you set this to 1, use the systemd-rpm-macros functionality described at https://docs.fedoraproject.org/en-US/packaging-guidelines/UsersAndGroups/
+%global with_systemd_usercreate 0
+%global pythonver python36
+
+# Fedora defaults
+%if 0%{?fedora}
+%global with_systemd_usercreate 1
+%global with_icons 1
+%global pythonver python3
+%endif
+
+%global _appvardir %{?_localstatedir}%{!?_localstatedir:/var}/www/fuss
+%global _appdir %{?_datarootdir}%{!?_datarootdir:%{_prefix}/share}/fuss
+%global _user fuss
+
+%define devtty "/dev/null"
+%define debug_package %{nil}
+%global _python_bytecompile_errors_terminate_build 0
+
+Summary: file upload and storage service web app
+Name: fuss
+Version: 0.0.2
+Release: 1
+License: GPL 3.0
+Source0: %{name}_%{version}.orig.tar.gz
+%if 0%{?with_systemd_usercreate}
+Source1: extra/%{name}.sysusers
+%endif
+%if ! 0%{?fedora}
+Patch1: extra/%{name}-el7.patch
+%endif
+URL: https://bgstack15.wordpress.com/
+#Distribution:
+#Vendor:
+Packager: B. Stack <bgstack15@gmail.com>
+Requires: %{pythonver}-flask
+Requires: %{pythonver}-uwsgidecorators
+Requires: uwsgi-plugin-%{pythonver}
+Requires: uwsgi-logger-file
+%if 0%{?fedora}
+Requires: %{pythonver}-magic
+Requires: %{pythonver}-flask-script
+%endif
+# Mandatory pip3 requirements: flask-script, python-magic
+%if 0%{?with_icons}
+Requires: /usr/bin/xvfb-run
+%if 0%{?fedora}
+Requires: %{pythonver}-gobject
+%else
+# The following are needed for CentOS7 pip3 install --user PyGObject
+Requires: cairo-gobject-devel
+Requires: gcc
+Requires: gobject-introspection-devel
+Requires: gtk3-devel
+Requires: python36-gobject
+Requires: python3-devel
+%endif
+%endif
+#BuildRequires: txt2man
+%if 0%{?with_systemd_usercreate}
+BuildRequires: systemd-rpm-macros
+%endif
+%if 0%{?fedora} || 0%{?rhel} >= 8
+Suggests: httpd
+%endif
+Buildarch: noarch
+
+%description
+File Upload and Storage Service is a demo flask application that can
+be used for whatever purposes you want.
+
+%prep
+%setup -q -c %{name}
+test -d "%{name}" && cd "%{name}"
+test -d "%{name}-master" && cd "%{name}-master"
+%if ! 0%{?fedora}
+%patch1 -p1
+%endif
+
+%build
+export srcdir="extra"
+test -d "%{name}" && cd "%{name}"
+%make_build -C "${srcdir}"
+
+%install
+export srcdir="extra"
+test -d "%{name}" && cd "%{name}"
+%make_install -C "${srcdir}" \
+ with_systemd=YES \
+ with_init=NO \
+ with_pip_helper=YES
+%if 0%{?with_systemd_usercreate}
+install -p -D -m 0644 %{SOURCE1} %{buildroot}%{_sysusersdir}/%{name}.conf
+%endif
+exit 0
+
+%clean
+rm -rf %{buildroot}
+
+%pre
+# Reference: squid.spec
+%if 0%{?with_systemd_usercreate}
+%sysusers_create_compat %{SOURCE1}
+%else
+if ! getent group %{_user} 1>/dev/null 2>&1 ;
+then
+ /usr/sbin/groupadd --system --gid 723 %{_user}
+fi
+if ! getent passwd %{_user} 1>/dev/null 2>&1 ;
+then
+ /usr/sbin/useradd --system --gid 723 \
+ --uid 723 --comment "FUSS system user" \
+ --home-dir %{_appvardir} --shell /sbin/nologin \
+ %{_user}
+fi
+%endif
+exit 0
+
+%preun
+%systemd_postun_with_restart %{name}.service
+
+%post
+%systemd_post %{name}.service
+
+%postun
+%systemd_postun_with_restart %{name}.service
+
+%files
+%if 0%{?with_systemd_usercreate}
+%{_sysusersdir}/%{name}.conf
+%endif
+%attr(0644, %{_user}, %{_user}) %config(noreplace) %{_sysconfdir}/%{name}.conf
+%attr(0644, %{_user}, %{_user}) %config(noreplace) %{_sysconfdir}/%{name}.wsgi.ini
+%attr(0644, %{_user}, %{_user}) %{_libexecdir}/%{name}/%{name}.py
+%attr(0755, %{_user}, %{_user}) %{_sbindir}/%{name}.bin
+%attr(0644, %{_user}, %{_user}) %{_appdir}/static/*
+%attr(0644, %{_user}, %{_user}) %{_appdir}/templates/*
+%attr(0755, %{_user}, %{_user}) %dir %{_appdir}/static
+%attr(0755, %{_user}, %{_user}) %dir %{_appdir}/templates
+%attr(0755, %{_user}, %{_user}) %dir %{_appvardir}/upload
+%attr(0755, %{_user}, %{_user}) %dir %{_appdir}
+%attr(0755, %{_user}, %{_user}) %dir %{_appvardir}
+%attr(0755, -, -) %{_libexecdir}/%{name}/pip-helper.sh
+%attr(0644, root, root) %{?_unitdir}%{!?_unitdir:/usr/lib/systemd/system}/%{name}.service
+%attr(0644, root, root) %{_sysconfdir}/httpd/conf.d/%{name}.conf
+%attr(0755, %{_user}, %{_user}) %dir %{?_localstatedir}%{!?_localstatedir:/var}/log/%{name}
+%{_defaultdocdir}/%{name}
+
+%changelog
+* Fri Sep 24 2021 B. Stack <bgstack15@gmail.com> - 0.0.2-1
+- Upstream update
+
+* Tue Jan 05 2021 B. Stack <bgstack15@gmail.com> - 0.0.1-1
+- Initial release
diff --git a/extra/stackbin.sysusers b/extra/stackbin.sysusers
new file mode 100644
index 0000000..d1ef475
--- /dev/null
+++ b/extra/stackbin.sysusers
@@ -0,0 +1,3 @@
+# Part of stackbin package
+#Type Name ID GECOS Home directory Shell
+u stackbin - "FUSS system user" /var/www/stackbin /sbin/nologin
diff --git a/stackbin.py b/stackbin.py
index bcfd3d5..e8948fd 100755
--- a/stackbin.py
+++ b/stackbin.py
@@ -5,6 +5,7 @@ from datetime import datetime, timedelta
from itsdangerous import Signer
from flask import (Flask, request, url_for, redirect, g, render_template, session, abort)
from flask_sqlalchemy import SQLAlchemy
+from werkzeug.middleware.proxy_fix import ProxyFix
from pytimeparse.timeparse import timeparse # python3-pytimeparse
# uwsgidecorators load will fail when using initdb.py but is also not necessary
try:
@@ -283,5 +284,13 @@ def favicon():
except:
abort(404)
+@app.route('/set')
+def get_proxied_path():
+ if 'HTTP_X_FORWARDED_PREFIX' in request.environ:
+ pl = len(dict(request.headers)["X-Forwarded-Host"].split(", "))
+ #prefix = request.environ['HTTP_X_FORWARDED_PREFIX']
+ app.wsgi_app = ProxyFix(app.wsgi_app,x_for=pl,x_host=pl,x_port=pl,x_prefix=pl,x_proto=pl)
+ return redirect(url_for('new_paste'))
+
if __name__ == "__main__":
app.run()
diff --git a/stackbin.wsgi.ini b/stackbin.wsgi.ini
index cf35ffb..1ad33c0 100644
--- a/stackbin.wsgi.ini
+++ b/stackbin.wsgi.ini
@@ -1,9 +1,9 @@
[uwsgi]
# CentOS 7 uwsgi needs "python36" added to this list.
plugins = logfile, python36
-# Devuan does not.
+# Devuan Ceres does not.
#plugins = logfile
-http-socket = 0.0.0.0:5000
+http-socket = 127.0.0.1:4680
wsgi-file = stackbin.py
callable = app
touch-reload = stackbin.py
bgstack15